The Problem
- You have an XML schema with multiple XML namespaces.
- You generate a JAXB model with xjc.
- You build a JAXB document model and use the JAXB Marshaller to create XML from the model.
- You want to override the default namespace prefixes
ns1, ns2, ...
created by the Marshaller.
Solution 1
You can implement a
NamespacePrefixMapper
and pass it to the Marshaller
Marshaller m = context.createMarshaller(); NamespacePrefixMapper mapper = new MyNamespacePrefixMapper(); m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
Drawbacks:
- You need to implement the Mapper.
- The Marshaller property is implementation dependent.
- When you use a standalone version of the JAXB Reference Implementation and not the one embedded in Oracle's JDK 6, the property name must be replaced by
com.sun.xml.bind.namespacePrefixMapper
.
Solution 2
Manually create the
package-info.java
source file which is normally generated by xjc:@XmlSchema(namespace = "urn:example.com:foo", xmlns = { @XmlNs(namespaceURI = "http://example.com/namespaces/bar", prefix = "bar"), @XmlNs(namespaceURI = "urn:example.com:foo", prefix = "") }, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package com.example.foo.jaxb; import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlSchema;
This is enough to make the Marshaller use the prefixes defined in the
@XmlNs
annotations.Now you only need to make sure that xjc does not overwrite or duplicate the
package-info.java
source file by setting the -npa
option.Working with Maven and the
maven-jaxb2-plugin
, you simply put your customized package-info.java
under src/main/java
and add the -npa
option to the plugin configuration:<plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.7.5</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <extension>true</extension> <args> <arg>-npa</arg> </args> </configuration> </plugin>
Update 21 March 2011: This approach does not work with the JAXB version contained in Oracle's JDK 1.6.0_24. You have to use a more recent version of the JAXB reference implementation by including the following dependency:
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.2</version> </dependency>
14 comments:
Will this work on WebServices as well? I tried manually modifying my package-info.java file and it doesn't effect the SOAP response.
I haven't tried this with web services, but I don't see why it shouldn't work as long as you use the proper version of JAXB. It doesn't work with the 2.1 version incorporated in JDK 1.6.0.
Solution 2 work in JDK 7
I did not have JDK 7 but when i added JAXB 2.2 as mentioned in the post, It worked. Thanks a lot
I was already using package-info.java but it was not adding prefix.
I did not have JDK 7 too, but adding jaxb-impl in pom.xml file solved my issue. Thanks a lot.
Thanks! Helped me a lot.
Have a look at the namespace-prefix plugin (http://java.net/projects/jaxb2-commons/pages/Namespace-prefix) which implements solution #2 in an automated way.
Great, especially the Ant solution
Perfect ! it works ....
This is amazing, finally saved me after hours and hours of exploration. Great work. Thanks a lot
Thanks a lot, worked like a charm.
Thank a lot it works!!!!!!!
Hello, I am trying to build a bottom up WS using JAX-WS. wsgen generates the wsdl from the annotated classes.
I would like to remove any prefix, even if possible also the namespace in the request and response.
I tried several things, but just can't get it to work..
Thanks
Thanks, nice tips
Post a Comment