Missing @XmlRootElement when creating client from wsdl

I have a question regarding the use of a web service based on a third-party wsdl file.

I took the given wsdl and generated 120 + java files. This process was performed using xjc . In Sping, I was able to successfully create a couple of JUnit tests by invoking a couple of open services.

But to successfully test these services, I had to add the @XmlRootElement annotation to the generated java files. Otherwise, I would encounter an error indicating

"com.sun.istack.SAXException2: failed to create marshal type" com.beam.services.client.UserGetRequestData "as an element because it is missing the annotation @XmlRootElement"

.

I have exhausted my search ... I do not control how a wsdl file is created / structured. How can I start generating java files to make sure that the @XmlRootElement annotation is included or is it about writing client-side code to avoid the error above?

Thanks.

+4
source share
2 answers

If you really need @XmlRootElement, you can use simple binding mode if your type is used for only one element. The reason JAXB does not include default annotation and how to use simple binding is explained here: https://community.oracle.com/blogs/kohsuke/2006/03/03/why-does-jaxb-put-xmlrootelement-sometimes -not-always :

your schema may be used by other schemas that XJC does not compile right now

and

Such a concept is not defined in the specification, but as an experiment we have such an aggressive optimization mode in XJC, previously called the “easy way to bind”.

The pattern seems to have been lost when the blog was moved, but it looked like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="1.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionbindingprefixes="xjc"> <xs:annotation> <xs:appinfo> <jaxb:globalbindings> <xjc:simple/> </jaxb:globalbindings> </xs:appinfo> </xs:annotation> <xs:element name="foo" type="bar"/> <xs:complextype name="bar"/> </xs:schema> 

Another possibility is to wrap it in a JAXBElement. ObjectFactory should include a method for creating these wrapped objects.

+1
source

If you are using mavem then check out this link that worked for me.

Create a Maven Project. Below you can see the POM:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.zmeu</groupId> <artifactId>zmeu-blog-maven-jaxb</artifactId> <version>1.0-SNAPSHOT</version> <name>ZMEU Blog Maven JAXB</name> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.8.0</version> <configuration> <schemaDirectory>src/main/resources/schema</schemaDirectory> <bindingDirectory>src/main/resources/schema</bindingDirectory> <generatePackage>org.zmeu.blog.jaxb</generatePackage> <strict>false</strict> <extension>true</extension> <plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.6.2</version> </plugin> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics-annotate</artifactId> <version>0.6.2</version> </plugin> </plugins> <args> <arg>-Xannotate</arg> <arg>-XtoString</arg> </args> </configuration> <executions> <execution> <id>generate</id> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics-runtime</artifactId> <version>0.6.2</version> </dependency> </dependencies> </project> 

Write an XML Schema (schema.xsd):

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <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> 

Configure JAXB bindings (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> 

Run the build using the mvn clean install command. Build must be successful. The generated classes will be located in the target / generated-sources / xjc directory. The following is a snippet from the created User class:

 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "user", propOrder = {}) @XmlRootElement(name = "user") public class User implements Serializable, ToString { 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; } 

You are done!

+1
source

Source: https://habr.com/ru/post/1390314/


All Articles