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