web-dev-qa-db-fra.com

Comment générer des classes jaxb à partir de xsd en utilisant gradle, jaxb et xjc, les classes doivent avoir XmlRootElement

Nous essayions de générer des classes JAXB à l'aide de gradle, xsd et xjc, et les classes JAXB devraient avoir des annotations XmlRootElement afin qu'elles puissent être utilisées pour s'exposer en tant que réponse de service Web. Nous suivions ce lien http://azagorneanu.blogspot.com/2011/09/configure-maven-to-generate-classes.html , cela nous a beaucoup aidés, mais nous n'avons pas trouvé d'exemple en particulier. Gradient seulement. Nous avons donc compris peu de choses que nous allons partager comme réponse.

11
aamir

build.gradle devrait ressembler à ci-dessous

    buildscript {
    repositories {
    mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "net.saliman:gradle-cobertura-plugin:2.2.4"
        classpath 'com.github.jacobono:gradle-jaxb-plugin:1.3.5'

    }
}
apply plugin: 'com.github.jacobono.jaxb'
dependencies {
    jaxb 'com.Sun.xml.bind:jaxb-xjc:2.2.7'
    jaxb "org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.6.5"
    jaxb "org.jvnet.jaxb2_commons:jaxb2-basics:0.6.4"
    jaxb "org.jvnet.jaxb2_commons:jaxb2-basics-annotate:0.6.4"
}
configurations {
    jaxb
}
task jaxb(){
    description 'Converts xsds to classes'
    def jaxbTargetDir = file("generated")
    doLast {
    jaxbTargetDir.mkdirs()
    ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.jaxb.asPath)
    ant.jaxbTargetDir = jaxbTargetDir 
    ant.xjc(destdir: '${jaxbTargetDir}', package: 'com.sample.jaxbclasses', schema:'generated/schema.xsd', binding:'generated/binding.xjb', extension:'true'){
        arg(value: "-Xannotate")
        }
    }
}

schema.xsd

 

    <xs:element name="user" type="user" />
    <xs:element name="userList" type="userList" />

    <xs:complexType name="user">
        <xs:all>
            <xs:element name="id" type="xs:long" minOccurs="0" />
            <xs:element name="name" type="xs:string" />
            <xs:element name="registrationDate" type="xs:dateTime" />
        </xs:all>
    </xs:complexType>

    <xs:complexType name="userList">
        <xs:sequence>
            <xs:element name="user" type="user" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

</xs:schema>

binding.xjb

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings xmlns:jaxb="http://Java.Sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://Java.Sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:annox="http://annox.dev.Java.net" 
    xsi:schemaLocation="http://Java.Sun.com/xml/ns/jaxb http://Java.Sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    version="2.1">
    <jaxb:globalBindings>
        <!-- Use Java.util.Calendar instead of javax.xml.datatype.XMLGregorianCalendar for xs:dateTime -->
        <jaxb:javaType name="Java.util.Calendar" xmlType="xs:dateTime"
                parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" 
                printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />

        <!-- Force all classes implements Serializable -->
        <xjc:serializable uid="1" />
    </jaxb:globalBindings>

    <!-- Annotate the following classes with XmlRootElement -->
    <jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
        <jaxb:bindings node="xs:complexType[@name='user']">
            <annox:annotate>
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="user" />
            </annox:annotate>
        </jaxb:bindings>
        <jaxb:bindings node="xs:complexType[@name='userList']">
            <annox:annotate>
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="userList" />
            </annox:annotate>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

ci-dessous binding.xjb pourrait également être utilisé

<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://Java.Sun.com/xml/ns/jaxb" xmlns:xjc="http://Java.Sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
    <jxb:globalBindings>
      <xjc:simple />
    </jxb:globalBindings>
  </jxb:bindings>
</jxb:bindings>

Vous pouvez maintenant exécuter la tâche ' jaxb ', Tout défini. À votre santé!

User.Java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 
// See <a href="http://Java.Sun.com/xml/jaxb">http://Java.Sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2017.01.26 at 11:59:18 AM EST 
//


package com.sample.jaxbclasses;

import Java.io.Serializable;
import Java.util.Calendar;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;


/**
* <p>Java class for user complex type.
* 
 * <p>The following schema fragment specifies the expected content contained within this class.
* 
 * <pre>
* &lt;complexType name="user">
*   &lt;complexContent>
*     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
*       &lt;all>
*         &lt;element name="id" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
*         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
*         &lt;element name="registrationDate" type="{http://www.w3.org/2001/XMLSchema}dateTime"/>
*       &lt;/all>
*     &lt;/restriction>
*   &lt;/complexContent>
* &lt;/complexType>
* </pre>
* 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "user", propOrder = {

})
@XmlRootElement(name = "user")
public class User
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    protected Long id;
    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    protected Calendar registrationDate;

    /**
     * Gets the value of the id property.
     * 
     * @return
     *     possible object is
     *     {@link Long }
     *     
     */
    public Long getId() {
        return id;
    }

    /**
     * Sets the value of the id property.
     * 
     * @param value
     *     allowed object is
     *     {@link Long }
     *     
     */
    public void setId(Long value) {
        this.id = value;
    }

    /**
     * Gets the value of the name property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the value of the name property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setName(String value) {
        this.name = value;
    }

    /**
     * Gets the value of the registrationDate property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public Calendar getRegistrationDate() {
        return registrationDate;
    }

    /**
     * Sets the value of the registrationDate property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setRegistrationDate(Calendar value) {
        this.registrationDate = value;
    }

}
11
aamir
group 'com.example'
version '1.0-SNAPSHOT'

apply plugin: 'Java'

sourceCompatibility = 1.8
targetCompatibility = 1.8


repositories {
    mavenCentral()
}

project.ext {
    jaxbTargetDir = file("src/generated/Java")

}


configurations {
    xsd2Java
}

dependencies {
    xsd2Java "com.Sun.xml.bind:jaxb-xjc:2.2.6"
    xsd2Java "com.Sun.xml.bind:jaxb-impl:2.2.6"
}

task xsd2Java() {

    doLast {
        jaxbTargetDir.mkdirs()

        ant.taskdef(name: 'xjc', classname: 'com.Sun.tools.xjc.XJCTask', classpath: configurations.xsd2Java.asPath)
        ant.jaxbTargetDir = jaxbTargetDir


        ant.xjc(
                destdir: '${jaxbTargetDir}',
                package: 'com.example.request',
                schema: 'src/main/resources/XMLreq.xsd'
        )

        ant.xjc(
                destdir: '${jaxbTargetDir}',
                package: 'com.example.response',
                schema: 'src/main/resources/XMLres.xsd'
        )

    }
}
compileJava.dependsOn xsd2Java
5
grep

Ma version utilise gradle native feature pour générer des classes jaxb.

Éventuellement, si votre schéma dépend de xsd externes, utilisez la technique "Catalogue Oasis" pour résoudre localement le XSD externe. Dans ce cas également, désactivez les validations de schéma XML pour éviter les erreurs de validation.

Facultativement, vous pouvez ajuster vos classes jaxb avec une liaison jaxb personnalisée. (Jaxb-bindings.xjb)

Fondamentalement, il s’agit d’une tâche personnalisée de niveau, qui appelle la tâche XJCTask ant disponible dans la machine virtuelle Java. Dans mon exemple, les bibliothèques sont issues de Java 8. Le nom de la tâche est "generateSources" et doit être ajusté à l’emplacement de votre schéma.

configurations {
    jaxb // Only for generation purpose
}

dependencies {
    jaxb  'javax.xml.bind:jaxb-api:2.2.11' 
    jaxb  'com.Sun.xml.bind:jaxb-xjc:2.2.11'    
    jaxb  'com.Sun.xml.bind:jaxb-impl:2.2.11'
    jaxb  'com.Sun.xml.bind:jaxb-osgi:2.2.11'
}

task generateSources() {
    doLast {
        def jaxbTargetDir = file("$buildDir/generated/src/main/Java")

        if (!jaxbTargetDir.exists()) {
            jaxbTargetDir.mkdirs()
        }

        ant.taskdef(name: 'xjc', classname: 'com.Sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath)

        ant.xjc(
                destdir: "${jaxbTargetDir}",
                schema: "${projectDir}/src/main/resources/MySchema.xsd",
                binding: "${projectDir}/src/main/resources/jaxb-bindings.xjb",
                catalog: "${projectDir}/src/main/resources/catalog.xml",
                removeOldOutput: 'yes', extension: 'true'
        )
                {
                    arg(line: '-nv -disableXmlSecurity')
                }
    }
}

Si vous avez besoin de catalogues, créez un fichier "catalog.xml" qui pourrait ressembler à ceci:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catalog
    PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
           "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
    <system systemId="http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd" uri="xenc-schema.xsd" />
    <system systemId="http://www.w3.org/TR/xmlenc-core/xenc-schema.xsd" uri="xenc-schema.xsd" />
    <system systemId="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" uri="xmldsig-core-schema.xsd" />
</catalog>

Pour jaxbinding

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://Java.Sun.com/xml/ns/jaxb" version="2.1"
    xmlns:xjc="http://Java.Sun.com/xml/ns/jaxb/xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <globalBindings>
        <xjc:javaType
            adapter="org.gazpachoquest.sample.JodaLocalDateTimeConverter"
            name="org.joda.time.LocalDateTime" xmlType="xs:dateTime" />
    </globalBindings>
</bindings>

Si, en plus de la génération jaxb, vous devez inclure ces classes pour construire. Vous devez ajuster la mise en page source et les dépendances.

apply plugin: 'Java'

def generatedSourcesOutput = "$buildDir/generated/main/Java"

sourceSets {
    main {
        Java.srcDirs "$generatedSourcesOutput"
    }
}

configurations {
    jaxb
}

dependencies {
    jaxb  'javax.xml.bind:jaxb-api:2.2.11' 
    jaxb  'com.Sun.xml.bind:jaxb-xjc:2.2.11'    
    jaxb  'com.Sun.xml.bind:jaxb-impl:2.2.11'
    jaxb  'com.Sun.xml.bind:jaxb-osgi:2.2.11'

    compile 'com.Sun.xml.bind:jaxb-xjc:2.2.11'
    compile 'com.Sun.xml.bind:jaxb-impl:2.2.11'
    compile 'javax.xml.bind:jaxb-api:2.2.11'
}

compileJava {
    dependsOn generateSources
}

C'est tout!

Gradle configuration pour utiliser gradle-jaxb-plugin

Les valeurs mises en commentaire dans la configuration xjc sont les valeurs par défaut - modifiez-les si nécessaire.

buildscript {
    repositories gradle.repos

    dependencies {
    }
}

plugins {
    id "org.openrepose.gradle.plugins.jaxb" version "2.5.0"
    id 'groovy'
    id 'Java'
    id "org.springframework.boot" version "2.1.2.RELEASE"
    id 'checkstyle'
}

apply plugin: 'io.spring.dependency-management'
apply plugin: "org.openrepose.gradle.plugins.jaxb"
apply plugin: 'idea'
apply plugin: 'maven-publish'

repositories gradle.repos

configurations {
    jaxb
    codeq
    compile.exclude module: "spring-boot-starter-Tomcat"
}

jaxb {
    xjc {
        //taskClassname        = 'com.Sun.tools.xjc.XJC2Task'
        //xsdDir               = "${project.projectDir}/src/main/resources/schema"
        generateEpisodeFiles = false
        generatePackage      = 'com.flitech.flux.d365.orchestrator.generated.travelops.v24'
        destinationDir       = "${buildDir}/generated/src/main/Java"
        args                 = ["-Xannotate"]
    }
}

compileJava.dependsOn {
    'xjc'
}

sourceSets {
    main {
        Java {
            srcDirs jaxb.xjc.destinationDir
        }
        resources {
            srcDirs 'src/main/resources'
        }
    }
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudDependenciesVersion}"
    }
}

dependencies {

    // Jaxb dependencies
    jaxb group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: jaxbxjcVersion
    jaxb 'org.jvnet.jaxb2_commons:jaxb2-basics-annotate:1.0.4'
    jaxb 'org.slf4j:slf4j-log4j12:1.7.25'
    implementation group: 'javax.xml.bind', name: 'jaxb-api', version: jaxbApiVersion
}

et fichier gradle.properties

# JAXB Processing Properties
jaxbPluginVersion = 2.5.0
jaxbxjcVersion = 2.3.2
jaxbApiVersion = 2.3.1

et pour le lier avec Intellij, ajoutez ce qui suit à votre fichier build.gradle

idea.module.iml {
    whenMerged {
        dependsOn jaxb
    }
}
0
sweetfa