Preface:
It is also in actual work that jaxb is used to realize the mapping and conversion of xml to java objects. In practical applications, I have also encountered some interesting and fun things, which should be recorded.
This article mainly explains how jaxb generates the agreed xml message The idea of the implementation of the header is relatively small, and the method is a bit tricky, so it leads to a little confusion when taking the title of the blog post, ^_^.
Phenomenon:
Let's first define a simple java class and use it to generate its corresponding xml content.
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name="root") public static class TNode { @XmlElement(name="key", required = true) private String key; @XmlElement(name="value", required = true) private String value; } public static void main(String[] args) { TNode obj = new TNode("key_1", "val_1"); try { JAXBContext jc = JAXBContext.newInstance(TNode.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); StringWriter writer = new StringWriter(); marshaller.marshal(obj, writer); System.out.println(writer.toString()); } catch (JAXBException e) { e.printStackTrace (); } }
Note: This is a simple entity class, and the corresponding jaxb code to generate xml The
specific generation results are as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <key>key_1</key> <value>val_1</value> </root>
In the default xml header, there is one more standalone="yes" than the common one . Is there a way to remove this little tail?
Try the idea:
The Marshaller class defines a lot of properties, let's first see if there is any configuration related to the header.
public interface Marshaller { // *) Specify the encoding mode public static final String JAXB_ENCODING = "jaxb.encoding"; // *) Specify whether to support indentation and line breaks when outputting public static final String JAXB_FORMATTED_OUTPUT = "jaxb.formatted.output"; /** * The name of the property used to specify the xsi:schemaLocation * attribute value to place in the marshalled XML output. */ public static final String JAXB_SCHEMA_LOCATION = "jaxb.schemaLocation"; /** * The name of the property used to specify the * xsi:noNamespaceSchemaLocation attribute value to place in the marshalled * XML output. */ public static final String JAXB_NO_NAMESPACE_SCHEMA_LOCATION = "jaxb.noNamespaceSchemaLocation"; // *) Whether to generate a header public static final String JAXB_FRAGMENT = "jaxb.fragment"; }
It's a little disappointing that there are only two information related to the header, JAXB_ENCODING controls the encoding , JAXB_FRAGMENT controls the visibility of the header, and there is no configuration item for standalone visibility. It seems that this way is not feasible.
Solution:
I originally thought that jaxb provided some listeners to achieve this function, but I haven't studied it yet. Inadvertently, I saw a netizen write a code to output xml, and suddenly thought that he might have encountered the same problem, but he didn't explain why The purpose of doing this is written out.
We re-modify the code that generates xml:
public static void main(String[] args) { TNode obj = new TNode("key_1", "val_1"); try { JAXBContext jc = JAXBContext.newInstance(TNode.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // 1) Hide the generation of message headers, Marshaller.JAXB_FRAGMENT defaults to false marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); StringWriter writer = new StringWriter(); // 2) custom build writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); marshaller.marshal(obj, writer); System.out.println(writer.toString()); } catch (JAXBException e) { e.printStackTrace (); } }
Note: Two points, 1. Activate JAXB_FRAGMENT to true, hide jaxb to automatically generate xml header. 2. Customize output header information
Test it, the results are as follows:
<?xml version="1.0" encoding="UTF-8" ?> <root> <key>key_1</key> <value>val_1</value> </root>
Summary:
This can also be regarded as a blog hydrology, here is a study note, and I want to learn more about the performance optimization of jaxb and the internal implementation mechanism.