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 MarshallerMarshaller 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