Hi stackoverflow world,
I want to specify in a XSD that a specific element can be used as a XmlRootElement by JAXB.
I know how to add the annotation to the generated class: what I want to do is to specify that a element can be generated as a root element before the code generation.
I use external JAXB customizations (.xjb files).
The purpose is here to not modifying the schemas (as they are defining standards).
Anybody knows how do that?
Thanks!
NJ
Problem solved.
The JAXB plugin Annotate http://confluence.highsource.org/display/J2B/Annotate+Plugin do the job.
Add the following fragment in your jaxb binding file (external binding, i.e. a .xjb file):
<jaxb:bindings schemaLocation="csw/2.0.2/CSW-discovery.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='GetRecordsType']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="GetRecordsType" />
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
Do not forget to declare the namespaces:
<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"
jaxb:extensionBindingPrefixes="xjc annox" version="2.1">
...
</jaxb:bindings>
And use a ANT or MAVEN task http://confluence.highsource.org/display/J2B/User+Guide to proceed the generation of the sources.
I still search how to specify manually (without an xjc task with ant or maven) the JAXB extensions but it works now. (I have my own ANT script what's why I search to manually call XJC).
The JAXB extension mechanism is very convenient, have a look to JAXB2 Basics:
http://confluence.highsource.org/display/J2B/Home
Related
I'm using a standard xml schema, called isosts, I need to convert schema to java class using jaxb. In this xml schema, a lot of elements have attribute rid as type xs:IDREFS <xs:attribute name="rid" type="xs:IDREFS">. Jaxb converts xs:IDREFS to be list of Objects.
For my need, I want jaxb to make type xs:IDREFS to be just java string type in all the generated java class. And during marshall/unmarshall time, the value of attribute rid should all be handled as string. Since this is a standard schema, I have to customize jaxb. I'm not sure if this can be done in jaxb binding or adapter and how to do it. Can anyone help me?
This binding file (let's call it "binding.xjb) forces the type to String:
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb
http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<bindings schemaLocation="SomeSchemaName.xsd" node="/xs:schema">
<bindings node="//xs:attribute[#name='rid']">
<property>
<baseType>
<javaType name="java.lang.String"></javaType>
</baseType>
</property>
</bindings>
</bindings>
</bindings>
Compile the schema using
xjc -b binding.xjb SomeSchemaName.xsd
I am using ant wsimport to generate client stub from the wsdls. Also, I would like to generate client classes that implements Serializable. I would like to generate a different serialVersionUID for each class. I tried with the binding file that was shown below. But its generating same serialVersionUID for all the classes. Is there any way I can give my own serialVersionUID to each class?
<wsimport xendorsed="true" binding="binding.xml" debug="true" keep="true"
verbose="false" sourcedestdir="${generated}" wsdl="${src}${wsdl.file}"
wsdlLocation="${wsdl.file}">
</wsimport>
binding configuration
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<globalBindings>
<serializable uid="1" />
</globalBindings>
</bindings>
Just for the record, there is no way to generate a unique serialVersionUID for each generated class because it doesn't make sense to do so.
Let me explain :
A serialVersionUID represents a version of your class at a particular point in time. If you modify your class, your serialVersionUID should change.
So when the JDK deserialize objects of the same class, it knows to which version of your class to deserialize it to.
In the case of JAXB, since you generate all your classes at once every time it doesn't make sense to version all the classes individually. Simply because they can only change as a group. (Unless you take them out of your target folder..)
I hope that makes a little bit more sense.
This is the binding file we use, which does the trick for us.
<xs:schema elementFormDefault="qualified" version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.0"
jaxb:extensionBindingPrefixes="xjc">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:serializable />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
I'm using CXF's wsdl2java tool to create a java web service.
I have a wsdl file and a few XSD files and I know that it's possible to use a binding file to map namespaces and packages. My binding file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" jaxb:version="2.0">
<jaxb:bindings schemaLocation="SchemeA.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.a" />
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="SchemeB.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.b" />
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="SchemeC.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.c" />
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
My files:
A.wsdl (imports all .xsd files)
SchemeA.xsd
SchemeB.xsd
SchemeC.xsd
It works great for everything in this XSD schemes but not for wsdl's definition. I mean at the end my packages looks like this:
com.test.package.a
com.test.package.b
com.test.package.c
https.package_test_com.a.service
The last line bother me, and I would like it to look like this: com.test.package.a.service
The binding file is used by jaxb that manages bindings of paramater and responses but webservice is directly managed by cxf or jax-ws so you will need to specify this binding with -p option of wsdl2java as specified here http://cxf.apache.org/docs/wsdl-to-java.html
How do I customize the packages of the namespaces when using jax-ws to generate the java artifacts.
I'm running jax-ws iwsmport via maven.
I don't want to change the default package, I want to be able to map from more than one namespace to different packages.
<jaxb:bindings
schemaLocation="../../wscontract/src/main/resources/wsdl/address.xsd"
node="//xsd:schema[#targetNamespace='http://demo.iae.ws/address']">
<jaxb:schemaBindings>
<jaxb:package name="demo.ws.address" />
<jaxb:nameXmlTransform>
<jaxb:typeName prefix="Customer" />
</jaxb:nameXmlTransform>
</jaxb:schemaBindings>
</jaxb:bindings>
Use JAXB bindings with the wsimport -b switch. You can find some sample files here.
We hav an EJB, jws-anotated as a web service. It has a pretty complex pojo-model that generates an equally complex xsd. The pojos contain numerous java.util.Date. These all map to xs:dateTime.
This service is used as "business service" in Oracle(BEA) OSB(AquaLogic). We also have a "proxy service" which we map to the BS with XQuery (the OSB/AquaLogic way). The proxy service's xsd has xs:date for the corresponding fields.
For some reason, Oracle's implementation of XQuery does not support casting from xs:date to xs:dateTime(!).
I could solve this by casting to xs:string and concat:ing with "T00:00:00", however, i would rather try to get JAX-WS to generate an xsd with xs:date instead. Only, I can't find any info on how to do this (anotations?).
Can anyone give me a hint?
Kind regards,
Lars
I don't know specifically about Oracle, but for CXF there are utilities to do this mapping. You might be able to find a similar adapter for your config. Have a look at the following page. http://cxf.apache.org/docs/wsdl-to-java.html.
There are two options depending on whether you have your schema inside the WSDL or in a separate URL (I understand that your are in a Java first config, but that you are trying to do the conversion on the Proxy side).
<jaxws:bindings wsdlLocation="YOUR_WSDL_LOCATION"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[#targetNamespace='THE_NAMESPACE_OF_YOUR_SCHEMA']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime"/>
</jxb:globalBindings>
</jaxws:bindings>
</jaxws:bindings>
XSD : outside, JAXB syntax
<jxb:bindings version="2.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="file:<path><name>.xsd" node="/xs:schema">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime"/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
In our CXF, we use the mapping to avoid using Gregorian Calendar but you can probably use it to do the casting.