https://blog.csdn.net/liliang_11676/article/details/81837215
It has been appearing in the project recently Java At the beginning, due to the huge project and my temporary scheduling, the mutual conversion between object and XML is always in the clouds while writing code according to the requirements of the project leader. Recently, I slowly began to find out the specific reasons for use in the project. However, the encapsulated code in the project is always very large, because too many things need to be considered. For this, I can only explain it through a small Demo. In fact, many plug-ins are used in the project, which are light and convenient, and the encapsulation is easy to use, but here I explain JAXB( JavaArchitecture for XML Binding).
JAXB (Java Architecture for XML Binding) is an industry standard and a technology that can generate Java classes according to XML Schema. In this process, JAXB also provides a method to reverse generate the Java object tree from the XML instance document, and can rewrite the content of the Java object tree to the XML instance document. On the other hand, JAXB provides a fast and easy way to bind XML Schema to Java representation, so that Java developers can easily combine XML data and processing functions in Java applications.
Important classes and interfaces related to JAXB in JDK: (from Baidu Encyclopedia JAXB)
- The JAXBContext class is an application entry used to manage XML/Java binding information.
- Marshall interface to serialize Java objects into XML data.
- Unmarshaller interface to deserialize XML data into Java objects.
Important annotations related to JAXB in JDK: (from Baidu Encyclopedia JAXB)
- @XmlType, which maps a Java class or enumeration type to an XML schema type
- @XmlAccessorType(XmlAccessType.FIELD) controls the serialization of fields or attributes. FIELD means that JAXB will automatically bind each non static and non transient (annotated by @ XmlTransient) FIELD in the Java class to XML. Other values are xmlaccesstype Property and xmlaccesstype NONE.
- @XmlAccessorOrder, which controls the sorting of attributes and fields in JAXB binding classes.
- @XmlJavaTypeAdapter uses a customized adapter (that is, extending the abstract class XmlAdapter and overriding the marshal() and unmarshal() methods) to serialize Java classes into XML.
- @XmlElementWrapper, for an array or collection (that is, a member variable containing multiple elements), generates an XML element (called a wrapper) that wraps the array or collection.
- @XmlRootElement, which maps Java classes or enumeration types to XML elements.
- @XmlElement, which maps an attribute of a Java class to an XML element with the same name as the attribute.
- @XmlAttribute, which maps an attribute of a Java class to an XML attribute with the same name as the attribute.
In the above annotations, @ XMLType, @ XmlAccessorType, @ XmlRootElement are used most.
Reasons for using JAXB:
1. Sometimes there are many XML files in the project, but if these files can be operated through objects, many operation problems will be reduced, and it is more in line with the coding method of programmers,
2. In the project, sometimes there are a lot of data in entity classes in a page, and sometimes some data is not necessary, that is, these entity classes can be written through DTO, but sometimes these DTOs need to be pre stored instead of stored in the database, so there are two ideas, which can be stored in memory or on hard disk, At this point, Java objects can be stored in memory by converting them into XML files or String types.
3. Give a scenario. For example, there are many modules in a page, but these modules belong to a whole module. When the user operates several modules, but the data after operation is not the final data, first Save the data in the current page (Done), then go to other pages for other operations, and then go to this page, Then the data in the previous page should still exist and users can easily view it. However, due to the large number of modules, it will cause waste if it is saved to the database before, because it is not the final saving effect. When the user wants to Save, the final data will be saved to the database at this time. In this process, a large amount of temporary data will be used, and a good way to solve this problem is to Save the current data in the page with XML.
In this paper, I first give a mutual conversion between object and XML, and then elaborate three scenarios through the concept of module. Of course, the code is not difficult, and it is very simple to simulate. The concept in the project will be much more complex than this, and there will also be code writing for this process. Therefore, I just throw a brick to attract jade, so that readers can have this kind of thought as much as possible. If they encounter this kind of situation when writing the project at that time, they can transfer their ideas well.
After all, let's see how to convert Java objects to XML.
First, take a look at the structure diagram of the Java project:
First, give user Java this class
package com.xml; import java.io.Serializable; import java.util.Date; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * * @author Steven * */ @XmlAccessorType(XmlAccessType.FIELD) // XML Root ID in file @XmlRootElement(name = "User") // control JAXB Sorting of properties and fields in binding classes @XmlType(propOrder = { "userId", "userName", "password", "birthday", "money", }) public class User implements Serializable { private static final long serialVersionUID = 1L; // user Id private int userId; // user name private String userName; // User password private String password; // User birthday private Date birthday; // User Wallet private double money; public User() { super(); } public User(int userId, String userName, String password, Date birthday, double money) { super(); this.userId = userId; this.userName = userName; this.password = password; this.birthday = birthday; this.money = money; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "User [birthday=" + birthday + ", money=" + money + ", password=" + password + ", userId=" + userId + ", userName=" + userName + "]"; } }
At this time, the most important core code xmlutil is given to interoperate Java objects and XML files Java, in which there are two ways to convert, one is the XML conversion into object and string type, and the other is the conversion between object and XML file.
XMLUtil.java
package com.xml; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; /** * Encapsulates the code that converts XML into object and object into XML * * @author Steven * */ public class XMLUtil { /** * Convert objects directly to XML output of type String * * @param obj * @return */ public static String convertToXml(Object obj) { // Create output stream StringWriter sw = new StringWriter(); try { // utilize jdk Implementation of transformation class in JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = context.createMarshaller(); // format xml Output format marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Converting objects to output streams xml marshaller.marshal(obj, sw); } catch (JAXBException e) { e.printStackTrace(); } return sw.toString(); } /** * Convert the object into an xml file according to the path * * @param obj * @param path * @return */ public static void convertToXml(Object obj, String path) { try { // utilize jdk Implementation of transformation class in JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = context.createMarshaller(); // format xml Output format marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Converting objects to output streams xml // Create output stream FileWriter fw = null; try { fw = new FileWriter(path); } catch (IOException e) { e.printStackTrace(); } marshaller.marshal(obj, fw); } catch (JAXBException e) { e.printStackTrace(); } } @SuppressWarnings("unchecked") /** * Convert xml of String type to object */ public static Object convertXmlStrToObject(Class clazz, String xmlStr) { Object xmlObject = null; try { JAXBContext context = JAXBContext.newInstance(clazz); // Carry on Xml The core interface of the object Unmarshaller unmarshaller = context.createUnmarshaller(); StringReader sr = new StringReader(xmlStr); xmlObject = unmarshaller.unmarshal(sr); } catch (JAXBException e) { e.printStackTrace(); } return xmlObject; } @SuppressWarnings("unchecked") /** * Convert xml of type file to object */ public static Object convertXmlFileToObject(Class clazz, String xmlPath) { Object xmlObject = null; try { JAXBContext context = JAXBContext.newInstance(clazz); Unmarshaller unmarshaller = context.createUnmarshaller(); FileReader fr = null; try { fr = new FileReader(xmlPath); } catch (FileNotFoundException e) { e.printStackTrace(); } xmlObject = unmarshaller.unmarshal(fr); } catch (JAXBException e) { e.printStackTrace(); } return xmlObject; } }
The test class test is given below java
package com.xml; import java.util.Date; /** * * @author Steven * */ public class Test { public static void main(String[] args) { // Create the object to be converted User user = new User(1, "Steven", "@sun123", new Date(), 1000.0); System.out.println("---Convert objects to string Type xml Start---"); // Convert objects to string Type xml String str = XMLUtil.convertToXml(user); // output System.out.println(str); System.out.println("---Convert objects to string Type xml End---"); System.out.println(); System.out.println("---take String Type xml Convert to object Start---"); User userTest = (User) XMLUtil.convertXmlStrToObject(User.class, str); System.out.println(userTest); System.out.println("---take String Type xml Convert to object End---"); } }
The test classes of the second method are as follows:;
Test.java
package com.xml; import java.util.Date; /** * * @author Steven * */ public class Test { public static void main(String[] args) { // Create the object to be converted User user = new User(1, "Steven", "@sun123", new Date(), 1000.0); String path = "D:\\user.xml"; System.out.println("---Convert objects to File Type xml Start---"); XMLUtil.convertToXml(user, path); System.out.println("---Convert objects to File Type xml End---"); System.out.println(); System.out.println("---take File Type xml Convert to object Start---"); User user2 = (User) XMLUtil.convertXmlFileToObject(User.class, path); System.out.println(user2); System.out.println("---take File Type xml Convert to object End---"); } }
At this time, the file generated in D: \ is shown in Figure 3:
Open user XML, as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User>
<userId>1</userId>
<userName>Steven</userName>
<password>@sun123</password>
<birthday>2013-12-13T18:24:03.477+08:00</birthday>
<money>1000.0</money>
</User>
At this time, it is a process of mutual conversion between objects and XML, but there are many cases in practice. There is a sub module Computer in the User. At this time, it is necessary to take the Computer as an attribute of the User. The code at this time is as follows:
Computer.java
package com.xml; import java.io.Serializable; import java.util.Date; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * Computer * * @author Steven * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Computer") @XmlType(propOrder = { "serialNumber", "brandName", "productDate", "price" }) public class Computer implements Serializable { private static final long serialVersionUID = 1L; // serial number private String serialNumber; // Brand name private String brandName; // Generation date private Date productDate; // Price private double price; public Computer() { super(); } public Computer(String serialNumber, String brandName, Date productDate, double price) { super(); this.serialNumber = serialNumber; this.brandName = brandName; this.productDate = productDate; this.price = price; } public String getSerialNumber() { return serialNumber; } public void setSerialNumber(String serialNumber) { this.serialNumber = serialNumber; } public String getBrandName() { return brandName; } public void setBrandName(String brandName) { this.brandName = brandName; } public Date getProductDate() { return productDate; } public void setProductDate(Date productDate) { this.productDate = productDate; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }
The user Java content is as follows:
package com.xml; import java.io.Serializable; import java.util.Date; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * * @author Steven * */ @XmlAccessorType(XmlAccessType.FIELD) // XML Root ID in file @XmlRootElement(name = "User") // control JAXB Sorting of properties and fields in binding classes @XmlType(propOrder = { "userId", "userName", "password", "birthday", "money", "computers" }) public class User implements Serializable { private static final long serialVersionUID = 1L; // user Id private int userId; // user name private String userName; // User password private String password; // User birthday private Date birthday; // User Wallet private double money; // Owned computers private List<Computer> computers; public User() { super(); } public User(int userId, String userName, String password, Date birthday, double money) { super(); this.userId = userId; this.userName = userName; this.password = password; this.birthday = birthday; this.money = money; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public void setComputers(List<Computer> computers) { this.computers = computers; } public List<Computer> getComputers() { return computers; } @Override public String toString() { return "User [birthday=" + birthday + ", computers=" + computers + ", money=" + money + ", password=" + password + ", userId=" + userId + ", userName=" + userName + "]"; } }
The test class is
Test.java
package com.xml; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * * @author Steven * */ public class Test { public static void main(String[] args) { User user = new User(1, "Steven", "@sun123", new Date(), 1000.0); List<Computer> list = new ArrayList<Computer>(); list.add(new Computer("xxxMMeedd", "asus", new Date(), 4455.5)); list.add(new Computer("lenvoXx", "lenvo", new Date(), 4999)); user.setComputers(list); String path = "D:\\user.xml"; System.out.println("---Convert objects to File Type xml Start---"); XMLUtil.convertToXml(user, path); System.out.println("---Convert objects to File Type xml End---"); System.out.println(); System.out.println("---take File Type xml Convert to object Start---"); User user2 = (User) XMLUtil.convertXmlFileToObject(User.class, path); System.out.println(user2); System.out.println("---take File Type xml Convert to object End---"); } }
Here, only the conversion of File type is tested, and the results are as follows:
Generated user XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <User> <userId>1</userId> <userName>Steven</userName> <password>@sun123</password> <birthday>2013-12-13T18:36:08.508+08:00</birthday> <money>1000.0</money> <computers> <serialNumber>xxxMMeedd</serialNumber> <brandName>asus</brandName> <productDate>2013-12-13T18:36:08.508+08:00</productDate> <price>4455.5</price> </computers> <computers> <serialNumber>lenvoXx</serialNumber> <brandName>lenvo</brandName> <productDate>2013-12-13T18:36:08.508+08:00</productDate> <price>4999.0</price> </computers> </User>
Here we can see that there is another module in one module. This idea can be continuously extended in the project, which can temporarily store a lot of data and achieve the purpose of caching. After writing the code, you should have your own ideas. In this way, you can analyze it according to the specific situation in the project.
The Unmarshaller class enables client applications to convert XML data into a Java content object tree.
Remarks: Marshal (serialization, arrangement, sorting)
The Marshall class enables client applications to convert Java content trees back to XML data.
package hb.jaxb; public class Classroom { private int id; private String name; private int grade; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } public Classroom(int id, String name, int grade) { super(); this.id = id; this.name = name; this.grade = grade; } public Classroom() { super(); } }
package hb.jaxb; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Student { private int id; private String name; private int age; private Classroom classroom; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Classroom getClassroom() { return classroom; } public void setClassroom(Classroom classroom) { this.classroom = classroom; } public Student(int id, String name, int age, Classroom classroom) { super(); this.id = id; this.name = name; this.age = age; this.classroom = classroom; } //Nonparametric access function must be required, otherwise JXBContext Unable to parse normally. public Student() { super(); } }
be careful:
1. The model object to be converted must be annotated with @ XmlRootElement, and other objects in it do not need to be annotated
2. The model object to be converted must have a construction method without parameters, including the objects referenced in the object.
package hb.jaxb; import java.io.StringReader; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.junit.Test; public class TestJaxb { @Test public void beanToXML() { Classroom classroom = new Classroom(1, "software engineering", 4); Student student = new Student(101, "Zhang San", 22, classroom); try { JAXBContext context = JAXBContext.newInstance(Student.class); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(student, System.out); } catch (JAXBException e) { e.printStackTrace(); } } @Test public void XMLStringToBean(){ String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><student><age>22</age><classroom><grade>4</grade><id>1</id><name>software engineering</name></classroom><id>101</id><name>Zhang San</name></student>"; try { JAXBContext context = JAXBContext.newInstance(Student.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Student student = (Student)unmarshaller.unmarshal(new StringReader(xmlStr)); System.out.println(student.getAge()); System.out.println(student.getClassroom().getName()); } catch (JAXBException e) { e.printStackTrace(); } } }
JAXB (Java Architecture for XML Binding) is an industry standard and a technology that can generate Java classes according to XML Schema. In this process, JAXB also provides a method to reverse generate the Java object tree from the XML instance document, and can rewrite the content of the Java object tree to the XML instance document. On the other hand, JAXB provides a fast and easy way to bind XML Schema to Java representation, so that Java developers can easily combine XML data and processing functions in Java applications.
The JAXBContext class provides a client entry point to the JAXB API. It provides the abstraction to manage the XML/Java binding information required to implement the operations of JAXB binding framework, including unmarshalling, marshalling and validation.