Trong bài viết Kết hợp Java Reflection và Annotation tôi đã hướng dẫn các bạn tự viết một chức năng chuyển đổi Java Object sang XML. Trong bài này, tôi sẽ hướng dẫn các bạn sử dụng JAXB để chuyển đổi đối tượng Java Object thành Xml và ngược lại.
JAXB là viết tắt của Java Architecture for XML Binding, JAXB được tích hợp vào JDK bắt đầu từ phiên bản 6.0. JAXB cung cấp phương thức để ghi (marshal) đối tượng java sang XML và đọc (unmarshal) XML thành đối tượng java.
Một số Annotation được sử dụng trong JAXB:
- XmlRootElement: là một Annotation, sử dụng để đánh dấu phần tử gốc (root element) của một tài liệu xml.
- XmlAccessorType: là một Annotation, sử dụng để thông báo với JAXB rằng các trường hoặc thuộc tính sẽ được sử dụng. Các loại XmlAccessType:
- PUBLIC_MEMBER : là loại AccessType mặc định của Jaxb. Nó sẽ binding các phần tử là public fields, properties, hoặc được đánh dấu xml annotations.
- PROPERTY : Nó sẽ binding các phần tử được đánh dấu xml annotations hoặc properties.
- FIELD : Nó sẽ binding các phần tử được đánh dấu xml annotations hoặc fields.
- NONE : Nó sẽ binding các phần tử được đánh dấu xml annotations.
- XmlElementWrapper: là một Annotation sử dụng để đánh dấu đây là một phần cha và giá trị của nó là một Collection (có chứa tài liệu xml con).
- XmlElement: là một Annotation, sử dụng để đánh dấu đây là một phần tử của tài liệu xml.
- XmlAttribute: là một Annotation, sử dụng để đánh dấu đây là một thuộc tính của phần tử.
- XmlTransient: là một Annotation, sử dụng để đánh dấu thuộc tính này sẽ được bỏ qua, không nằm trong tài liệu xml.
- XmlType(propOrder={fieldNames}) : là một Annotation, sử dụng để đánh dấu thứ tự các field trong tài liệu xml.
JAXB Marshalling: chuyển object sang xml
Employee.java
package com.gpcoder.xml.jaxb; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; @XmlRootElement(name = "employee") @XmlAccessorType(XmlAccessType.FIELD) public class Employee { @XmlAttribute(name = "id") private int id; @XmlElement(name = "name") private String name; @XmlElement(name = "salary") private float salary; @XmlTransient private int age; /** * Bắt buộc phải có hàm khởi tạo không tham số */ public Employee() { } public Employee(int id, String name, float salary, int age) { super(); this.id = id; this.name = name; this.salary = salary; this.age = age; } 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 float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + ", age=" + age + "]"; } }
Department.java
package com.gpcoder.xml.jaxb; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(namespace = "http://gpcoder.com/jaxb") @XmlAccessorType(XmlAccessType.FIELD) public class Department { @XmlElement(name = "no") private String deptNo; @XmlElement(name = "name") private String deptName; @XmlElementWrapper(name = "employees") @XmlElement(name = "employee") private List<Employee> employees; /** * Bắt buộc phải có hàm khởi tạo không tham số */ public Department() { } public Department(String deptNo, String deptName) { this.deptNo = deptNo; this.deptName = deptName; } public String getDeptNo() { return deptNo; } public void setDeptNo(String deptNo) { this.deptNo = deptNo; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } @Override public String toString() { return "Department [deptNo=" + deptNo + ", deptName=" + deptName + ", employees=" + employees + "]"; } }
ObjectToXml.java
package com.gpcoder.xml.jaxb; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; public class ObjectToXml { public static void main(String[] args) throws Exception { JAXBContext contextObj = JAXBContext.newInstance(Department.class); Marshaller marshallerObj = contextObj.createMarshaller(); marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); Department dept = getDepartment(); // Write data to console marshallerObj.marshal(dept, System.out); // Write data to file xml marshallerObj.marshal(dept, new FileOutputStream("department.xml")); } private static Department getDepartment() { // Create employees List<Employee> employees = new ArrayList<>(); Employee emp1 = new Employee(1, "GP Coder", 1000, 28); Employee emp2 = new Employee(2, "LN Devil", 700, 27); employees.add(emp1); employees.add(emp2); // Create department Department department = new Department("D01", "IT Support"); department.setEmployees(employees); return department; } }
Thực thi chương trình trên, nội dung console như bên dưới và một file department.xml được tạo ra.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:department xmlns:ns2="http://gpcoder.com/jaxb"> <no>D01</no> <name>IT Support</name> <employees> <employee id="1"> <name>GP Coder</name> <salary>1000.0</salary> </employee> <employee id="2"> <name>LN Devil</name> <salary>700.0</salary> </employee> </employees> </ns2:department>
Giải thích hoạt động của chương trình trên như sau:
JAXB UnMarshalling: chuyển xml sang object
package com.gpcoder.xml.jaxb; import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; public class XMLToObject { public static void main(String[] args) { try { File file = new File("department.xml"); JAXBContext jaxbContext = JAXBContext.newInstance(Department.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Department dept = (Department) jaxbUnmarshaller.unmarshal(file); System.out.println(dept); } catch (JAXBException e) { e.printStackTrace(); } } }
Kết quả thực thi chương trình trên:
Department [deptNo=D01, deptName=IT Support, employees=[ Employee [id=1, name=GP Coder, salary=1000.0, age=0], Employee [id=2, name=LN Devil, salary=700.0, age=0] ] ]
Tài liệu tham khảo:
- https://docs.oracle.com/javase/tutorial/jaxb/intro/
- https://docs.oracle.com/javase/8/docs/technotes/guides/xml/jaxb/index.html
- https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/Unmarshaller.Listener.html
- http://blog.bdoughan.com/