Requirements: The policy system requires us to pass in a string in XML format, and the project accepts a JSON. Since the format of this XML is a bit unconventional, not all attributes are key-value pairs, as shown below:
Document your own experience doing this so you can recall it later
JSON to JAVA object
The general format is as follows:
So we create the corresponding entity class, because the final XML is China, so create a China class, and create the attribute Name and 4 custom classes according to the hierarchical relationship
China
Level 1: Beijing
Level 1: Shenzen
Level 2: Nanshan
Level 2: Futian
Add the annotation @JSONField(name = "name in JSON") to the property
By the way, rewrite toString, each custom class is
public static void main (String [] args) throws a JAXBException, IOException, DocumentException { // JSON parsed into objects - String troublesome because JSON written, to turn into a re-decoded Base64 actual String STR = "+ eUsCJ9fX0 eyJOYW1lIjoi5Lit5Zu9IiwiQmVpamluZyI6eyJOYW1lIjoi5YyX5LqsIn0sIlNoZW56aGVuIjp7Ik5hbWUiOiLmt7HlnLMiLCJOYW5zaGFuIjp7Ik5hbWUiOiLljZflsbEiLCJQcmljZSI6MTIzLCJEYXRlIjoiMjAxOC0wNC0yOCJ9LCJGdXRpYW4iOnsiTmFtZSI6Iuemj =" ;
STR = Base64Coder.decodeString(str);
// Call Google's FastJson, and the conversion is simple and successful. China china = JSON.toJavaObject(JSON.parseObject(str), China.class); System.out.println(china.toString()); }
Object to XML
First add the following two annotations on each custom class
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "converted XML name")
Then add annotations to each individual attribute, under the JSON annotation above, if it is a node:
@XmlElement(name = "node name")
If it is an attribute:
@XmlAttribute(name = "Attribute name")
Some special formats, such as Date, can set the format of XML. For example, in the requirement, I only need Date and not hours, minutes and seconds. So add on the corresponding Date property:
@XmlSchemaType(name = "date")
Go back to the method, use the package that comes with JDK for parsing, add a method, pass in the entity class and return a string
/** * @Title: beanToXml * @Description: JAVA object converted to XML string * @param application * @throws JAXBException * @throws PropertyException parameter description * @return void return type */ public static String beanToXml(Object object) throws JAXBException { JAXBContext jc = JAXBContext.newInstance(object.getClass()); Marshaller marshaller = jc.createMarshaller(); // whether to format the output marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false ); // set the encoding format marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8" ); // whether not Display header information marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true ); StringWriter writer = new StringWriter(); marshaller.marshal(object, writer); // Remove time zone information in date return writer.toString().replaceAll("\\+08:00", "" ); }
It's almost normal to this step, but there is actually nothing to display in the head, and there are still empty nodes using </>
There are many similar examples on the Internet, but there are all kinds of unsatisfactory ones. In fact, the solution is very simple, just turn it again!
remove empty nodes
/** * @Title: formatXmlEmptyElements * @Description: Format the empty node of the XML string, <example/> is converted to <example></example> * @param xml * @return * @throws IOException * @throws DocumentException parameter description * @return String 返回类型 */ public static String formatXmlEmptyElements(String xml) throws IOException, DocumentException { OutputFormat xmlFormat = OutputFormat.createPrettyPrint(); // Set the expansion empty node xmlFormat.setExpandEmptyElements( true ); StringWriter out = new StringWriter(); XMLWriter writer = new XMLWriter(out, xmlFormat); writer.write(DocumentHelper.parseText(xml)); return out.toString(); }
Put the complete main method
public static void main(String[] args) throws JAXBException, IOException, DocumentException { //json解析成对象 String str = "eyJOYW1lIjoi5Lit5Zu9IiwiQmVpamluZyI6eyJOYW1lIjoi5YyX5LqsIn0sIlNoZW56aGVuIjp7Ik5hbWUiOiLmt7HlnLMiLCJOYW5zaGFuIjp7Ik5hbWUiOiLljZflsbEiLCJQcmljZSI6MTIzLCJEYXRlIjoiMjAxOC0wNC0yOCJ9LCJGdXRpYW4iOnsiTmFtZSI6Iuemj+eUsCJ9fX0="; str = Base64Coder.decodeString(str); China china = JSON.toJavaObject(JSON.parseObject(str), China.class); System.out.println(china.toString()); // The object is parsed into XML format String xmlString = beanToXml(china); System.out.println(xmlString); // Add trailing blank node System.out.println(formatXmlEmptyElements(xmlString)); }
result: