JAXB

JAXB: Implementation of XML and Java object transfer

JAXB is an industry standard for interoperability between XML files and Java objects. JAXB is part of the JDK. We don't need to download a third-party JAR package to do this easily.Copy the code

Important classes and interfaces:

○ The JAXBContext class is an entry point to the application and is used to manage XML/Java binding information. ○ Marshaller interface to serialize Java objects to XML data. ○ Unmarshaller interface for deserializing XML data into Java objects.Copy the code

annotations

Annotations from XML to Java objects: ○ @xmlType: ○ @xmlElement: node that maps attributes of Java objects to XML ○ @xmlRootelement: root element of this class to XML ○ @XMlattribute: ○ @xmlAccessorType: specifies how Java object attributes are accessed when Java objects generate XML files. When converting complex objects, such as map types or formatting dates, etc. ○ @xmlAccessorOrder: sorts XML elements generated by Java objects Defining a field or attribute does not need to be mapped to XML ○ @xmlelementWrapper: Defines a parent node for an array element or collection elementCopy the code

Project implementation

Demo1: Demonstrates basic XML usage, such as @XMLRootelement, @XMLAccessorType, and @XMLElement

The base POJO class ClassRoomModel contains a variable name and a list of variables StudentModel

public class StudentModel { private int id; // Private String name; // name private String sex; // Gender} @xmlRootelement (name ="classRoom")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ClassRoomModel {
    @XmlElement(name="name")
    private String name;

    @XmlElement(name="student")
    private List<StudentModel> studentModelList;
}
Copy the code

Classroom. That is to be transformed XML

<? xml version="1.0" encoding="UTF-8"? > < classRoom > < name > total configuration name < / name > < student > < id > 1 < / id > < name > zhang < / name > < sex > male < / sex > < / student > < student > < id > 2 < / id > < name > and < / name > < sex > women < / sex > < / student > < / classRoom >Copy the code

Test class JAXBManager: Create JAXBContext objects, create Unmarshaller objects from JAXBContext objects, and use the Unmarshaller object implementation to convert XML into ClassRoomModel objects. Create a Marshaller object from the JAXBContext object, and use the Marshaller implementation to convert the ClassRoomModel object into an XML file

JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel.class); / / read from the XML file, and translated into Java objects you you = jaxbContext. CreateUnmarshaller (); InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom.xml");
System.out.println(JAXBManager.class.getClassLoader().getResource(""));
System.out.println(Thread.currentThread().getContextClassLoader().getResource("")); ClassRoomModel classRoomModel = (ClassRoomModel)unmarshaller.unmarshal(classRoomInputStream); System.out.println(JSON.toJSONString(classRoomModel)); / / save the file, convert Java objects into XML file Marshaller Marshaller. = jaxbContext createMarshaller (); marshaller.marshal(classRoomModel, new File("classroon-save.xml"));

Copy the code

Demo2: demonstrates the usage of @xmlattribute, @xmlJavatypeAdapter, and XmlAdapter

Basic POJO classes: ClassRoomModel2 contains a variable name and a list of variables StudentModel. Unlike the above class, StudentModel2 uses @xmlattribute to inject values from the attributes of the XML element, plus the Date object

@XmlAccessorType(value = XmlAccessType.FIELD)
public class StudentModel2 {
    @XmlAttribute(name = "id") private int id; // student id @xmlattribute (name ="name") private String name; // name @xmlattribute (name ="sex") private String sex; // Gender @xmlattribute (name ="birthDate") @xmlJavatyPeAdapter (value = datexMladapter.class) private Date birthDate; // birthday} @xmlRootelement (name ="classRoom")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ClassRoomModel2 {
    @XmlElement(name="name")
    private String name;

    @XmlElement(name="student")
    private List<StudentModel2> studentModelList;
}
Copy the code

XML file to be converted

<? xml version="1.0" encoding="UTF-8"? > <classRoom> <name> Configure the total name </name> <student id="1" name="Zhang" sex="Male" birthDate="1999-10-22" />
    <student id="2" name="Bill" sex="Female" birthDate="1997-12-23"  />
</classRoom>
Copy the code

StudentModel2 birthDate: @xmlJavatypeAdapter (value = DateXmlAdapter. Class), which converts the Date String to Date

public class DateXmlAdapter extends XmlAdapter<String, The time/Date > {/ private static final ThreadLocal < SimpleDateFormat > simpleDateFormatThreadLocalYYYYMMDD = new ThreadLocal<SimpleDateFormat>(){ @Override protected SimpleDateFormatinitialValue() {
            return new SimpleDateFormat("yyyy-MM-dd"); }}; @Override public Date unmarshal(String v) throws Exception { System.out.println(v);return simpleDateFormatThreadLocalYYYYMMDD.get().parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        System.out.println(v);
        returnsimpleDateFormatThreadLocalYYYYMMDD.get().format(v); }}Copy the code

Test class JAXBManager: The usage is the same as in the first demo, as detailed in the code

public static void main(String[] args){ try { JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel2.class); / / read from the XML file, and translated into Java objects you you = jaxbContext. CreateUnmarshaller (); InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom2.xml");
            System.out.println(JAXBManager2.class.getClassLoader().getResource(""));
            System.out.println(Thread.currentThread().getContextClassLoader().getResource("")); ClassRoomModel2 classRoomModel = (ClassRoomModel2)unmarshaller.unmarshal(classRoomInputStream); System.out.println(JSON.toJSONString(classRoomModel)); / / save the file, convert Java objects into XML file Marshaller Marshaller. = jaxbContext createMarshaller (); marshaller.marshal(classRoomModel, new File("classroon-save2.xml")); } catch (JAXBException e) { e.printStackTrace(); }}Copy the code

Exception handling

If you do not append @xmlAccessorType (value = XmlAccessType.FIELD) to the class, the following exception may be thrown. The default access level for @xmlAccessorType is XmlAccessType.PUBLIC_MEMBER, so if a private member variable in a Java object sets getter/setter methods for public permissions, Do not use @xmlElement and @XMlattribute annotations on private variables. If you generate XML from Java objects, you will get an error that the same attribute exists twice in a Java class.

Com. Sun. XML. Internal. Bind. V2. The runtime. IllegalAnnotationsException: two counts of IllegalAnnotationExceptions two attributes of a class with the same name"name"this problem is related to the following location: at public java.lang.String com.hry.java.xml.model.ClassRoomModel.getName() at com.hry.java.xml.model.ClassRoomModel this  problem is related to the following location: at private java.lang.String com.hry.java.xml.model.ClassRoomModel.name at com.hry.java.xml.model.ClassRoomModelCopy the code

code

See Github for more details