Using JAXB to transform XML and JavaBean (supporting generics)

Posted by manohoo on Thu, 24 Oct 2019 12:37:06 +0200

I saw that someone else had a medal of 1024, and I specially left one on October 24 this year to see if I could get it.

In the daily development, it may involve the mutual call between interfaces. Although under the promotion of the concept of microservice, many companies use the lightweight JSON format as the serialization format, there are still some companies that have some messages in XML format. Recently, when docking with a partner, they encountered XML messages. It's difficult to try to use one message parameter by one under the crisp conversion of JSON message, or to directly convert the message to Bean. Next, I learned about some plug-ins. Because generics are used in the code, I chose JAXB after multiple comparisons. Next, I will introduce the use of JAXB.

1. Create two beans as the conversion template (using generics), @ XmlRootElement(name = "GIRL") is used as the encapsulation node of the corresponding message; @ XmlAccessorType(XmlAccessType.FIELD) means that only variables are converted to entities, which is very nice to use with @ Data.

package com.example.dragon.main.dao.model.xmlutil;

import lombok.Data;

import javax.xml.bind.annotation.*;
import java.util.List;

/**
 * @ClassNAME girl
 * @Description Girl object
 * @Author XiongMao
 * @Date 2019-9-8
 */
@Data
@XmlRootElement(name = "GIRL")
@XmlAccessorType(XmlAccessType.FIELD)
public class Girl<T> {
    @XmlElement(name = "NAME")
    private String name;
    /**
     * XmlAnyElement This annotation can be used to call the xsi:type and other information in the generated xml. With this annotation, @ XmlElement cannot be used.
     *  The @ XmlRootElement annotation needs to be added to the entity corresponding to the generic
     *  XmlElementWrapper This annotation can wrap a node outside the collection
     */
    @XmlAnyElement(lax = true)
    private T ageAndSex;
}
package com.example.dragon.main.dao.model.xmlutil;

import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @ClassNAME AgeAndSex
 * @Description Age and gender target
 * @Author XiongMao
 * @Date 2019-9-8
 */
@Data
@XmlRootElement(name="AGEANDSEX")
@XmlAccessorType(XmlAccessType.FIELD)
public class AgeAndSex {
    @XmlElement(name="AGE")
    private String age;
    @XmlElement(name="SEX")
    private String sex;
}

2. Make a tool class to encapsulate and transform the code. There are comments in the code. Some blog content has been used for reference. I have forgotten for a long time. If you find any, please let me know:

package com.example.dragon.main.util;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * @ClassNAME XmlUtil
 * @Description XML Convert to bean
 * @Author XiongMao
 * @Date 2019-9-7
 */
public class XmlUtil {

    /**
     * @Description bean Turn to xml
     * @Param [t]
     * @Return java.lang.String
     */
    public static <T> String beanToXml(T t) throws JAXBException {
        //Get a new instance of the JAXBContext class. Parameter is the address of the class
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        //Create a marshaler object that you can use to transform a java content tree into XML data.
        Marshaller m = context.createMarshaller();
        //Create a StringWriter stream to write the received object stream to an xml string
        StringWriter sw = new StringWriter();
        //Calling marshal method for transformation
        m.marshal(t,sw);
        //Flow the read StringWriter to String to return
        return sw.toString();
    }

    /**
     * @Description bean Convert to XML (generic use)
     * @Param [t]
     * @Return java.lang.String
     */
    public static <T> String beanToXml(T t, Class c) throws JAXBException {
        //Get a new instance of the JAXBContext class. Parameter is the address of the class
        JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
        //Create a marshaler object that you can use to transform a java content tree into XML data.
        Marshaller m = context.createMarshaller();
        //Create a StringWriter stream to write the received object stream to an xml string
        StringWriter sw = new StringWriter();
        //Calling marshal method for transformation
        m.marshal(t,sw);
        //Flow the read StringWriter to String to return
        return sw.toString();
    }

    /**
     * @Description xml Turn to bean
     * @Param [xml, t]
     * @Return T
     */
    public static <T> T xmlToBean(String xml, T t) throws JAXBException {
        ////Get a new instance of the JAXBContext class. Parameter is the address of the class
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        //Create an Unmarshaller object that can be used to transform XML data into a java content tree.
        Unmarshaller um = context.createUnmarshaller();
        //Create a StringReader to convert xml messages into streams
        StringReader sr = new StringReader(xml);
        //Call unmarshal to convert and force the Object type to the caller's type
        t = (T) um.unmarshal(sr);
        //Return object to caller
        return t;
    }

    /**
     * @Description xml Convert to bean (generic use)
     * @Param [xml, t]
     * @Return T
     */
    public static <T> T xmlToBean(String xml, T t, Class c) throws JAXBException {
        ////Get a new instance of the JAXBContext class. Parameter is the address of the class
        JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
        //Create an Unmarshaller object that can be used to transform XML data into a java content tree.
        Unmarshaller um = context.createUnmarshaller();
        //Create a StringReader to convert xml messages into streams
        StringReader sr = new StringReader(xml);
        //Call unmarshal to convert and force the Object type to the caller's type
        t = (T) um.unmarshal(sr);
        //Return object to caller
        return t;
    }
}

3. Next, do a main method to test the following running results:

main Method:
        Girl girl = new Girl();
        girl.setName("Xiaohong");
        AgeAndSex ageAndSex = new AgeAndSex();
        ageAndSex.setAge("18");
        ageAndSex.setSex("female");
        girl.setAgeAndSex(ageAndSex);
        System.out.println("The value of the assembled object is:" + girl);
        //Method call and output
        Girl newGirl = new Girl();
        String xml;
        try {
            xml = XmlUtil.beanToXml(girl, AgeAndSex.class);
            System.out.println("bean Turn into xml The format is:" + xml);
            newGirl = XmlUtil.xmlToBean(xml, newGirl, AgeAndSex.class);
            System.out.println("xml Turn into bean The format is:" + newGirl);
        } catch (JAXBException e) {
            e.printStackTrace();
        }

//Result:
    //The value of the assembled object is: Girl(name = small red, ageAndSex=AgeAndSex(age=18, sex = female))
    bean Turn into xml The format is:<?xml version="1.0" encoding="UTF-8" standalone="yes"?><GIRL><NAME>Small    red</NAME><AGEANDSEX><AGE>18</AGE><SEX>female</SEX></AGEANDSEX></GIRL>
    xml Turn into bean The format is: Girl(name=Xiaohong, ageAndSex=AgeAndSex(age=18, sex=female))

In fact, it's quite simple to use, because the time is limited and I haven't studied his principle. If I know it, I can add it. It's still recommended that you learn more about the principles of technology, because today's technology implementation is becoming simpler and simpler, but you are also far away from the principles.

Topics: xml Java JSON Lombok