This article introduces advanced use of JAXB and namespace processing
Use Add default namespace
Add a file under the package that needs to add a namespace, and then add the @XmlSchema annotation, so that the namespace will be automatically added when the entire package is serialized.
@XmlSchema(namespace = "") package ; import ;
Namespace prefix processing
I believe that the famous ns2, nsXX has caused a lot of headaches for many people like the following
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:classA xmlns:ns2=""> <classAId>11</classAId> <ClassAName>A1</ClassAName> <classB> <ClassBId>22</ClassBId> <ClassBName>B2</ClassBName> </classB> </ns2:classA>
Solution 1 (not recommended):
Add @XmlSchema annotation and set the attribute xmlns
@XmlSchema( xmlns = { @XmlNs(namespaceURI = "", prefix = "rabbit"), @XmlNs(namespaceURI = "", prefix = "blog")}) package ; import ; import ;
ClassA is as follows
Package ; import .*; @XmlRootElement(namespace="") @XmlAccessorType() public class ClassA { private int classAId; @XmlElement(name="ClassAName") private String classAName; private ClassB classB; public int getClassAId() { return classAId; } public void setClassAId(int classAId) { = classAId; } public String getClassAName() { return classAName; } public void setClassAName(String classAName) { = classAName; } public ClassB getClassB() { return classB; } public void setClassB(ClassB classB) { = classB; } }
The serialization result is as follows. You can see that the namespace prefix has been modified as we expected. Here we should note that the namespace specified when adding the @XmlRootElement(namespace="") annotation of the entity class that requires a custom prefix must be the same as the defined prefix, otherwise a prefix like nsXX will still be generated.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <rabbit:classA xmlns:rabbit="" xmlns:blog=""> <classAId>11</classAId> <ClassAName>A1</ClassAName> <classB> <ClassBId>22</ClassBId> <ClassBName>B2</ClassBName> </classB> </rabbit:classA>
Things to note
1. If jdk version 1.6 needs to add references to both packages, jaxb-core-2.2. and jaxb-impl-2.2., otherwise even if the package-info XmlSchema annotation is set, the xmlns annotation cannot take effect. If jdk 1.7 does not need to add it
2. Using the prefix defined by XmlSchema will take effect on the entire package. It is impossible to define a separate prefix for each entity class, which is very inflexible, so this method is not recommended.
Solution 2 (recommended):
The same method is the same. If the jdk version is 1.6, you need to add references to the two packages, jaxb-core-2.2. and jaxb-impl-2.2., but the second method does not need to add package-info, so you do not need to define XmlSchema.
The idea is to implement the NamespacePrefixMapper abstract class and rewrite the getPreferredPrefix method. When you see the method name, you should understand it. That is, rewrite the namespace prefix method when serializing. In order to simplify the implementation of the class anonymous internal class.
("", new NamespacePrefixMapper() { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { if (("")) return "abc"; return suggestion; } });
As shown above, when serializing, judge namespaceUri, which is the namespace we define, and then return our customized prefix. The suggestion parameter is the default prefix. If you are interested, you will find that the suggestion is a prefix such as ns2. If you judge the namespace to be customized here, you can completely control the custom prefix. Compared with the first method, you can realize the namespace prefix control of each entity class, and use the serialization result after method two:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <abc:classA xmlns:abc=""> <classAId>11</classAId> <ClassAName>A1</ClassAName> <classB> <ClassBId>22</ClassBId> <ClassBName>B2</ClassBName> </classB> </abc:classA>
Using the serialization method after method two
package ; import ; import ; import .*; import ; import .; public class XmlUtil { public static String toXML(Object obj) { try { JAXBContext context = (()); Marshaller marshaller = (); (Marshaller.JAXB_ENCODING, "UTF-8");// // Encoding format (Marshaller.JAXB_FORMATTED_OUTPUT, true);// Whether to format the generated xml string (Marshaller.JAXB_FRAGMENT, false);// Whether to omit the xm header declaration information ("", new NamespacePrefixMapper() { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { if (("")) return "abc"; if (("")) return "blog"; return suggestion; } }); StringWriter writer = new StringWriter(); (obj, writer); return (); } catch (Exception e) { throw new RuntimeException(e); } } @SuppressWarnings("unchecked") public static <T> T fromXML(String xml, Class<T> valueType) { try { JAXBContext context = (valueType); Unmarshaller unmarshaller = (); return (T) (new StringReader(xml)); } catch (Exception e) { throw new RuntimeException(()); } } }
Now we have basically solved the problem of jaxb serializing xml namespace and prefix, but there are still many problems, such as how to ignore the namespace during serialization and deserialization, how to use @XmlRootElement to control the default namespace of each entity class, that is, eliminate the namespace prefix
The next article continues to go deeper, Java XML operation: JAXB plays with namespace
Finally, give the maven references to the two packages jaxb-core-2.2. and jaxb-impl-2.2.
<dependency> <groupId></groupId> <artifactId>jaxb-core</artifactId> <version>2.2.7</version> </dependency> <dependency> <groupId></groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.7</version> </dependency>
You can also download it on your own/
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.