- package ycl.learn.xml.jaxb;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import javax.xml.bind.JAXBContext;
- import javax.xml.bind.JAXBException;
- import javax.xml.bind.Marshaller;
- import javax.xml.bind.Unmarshaller;
- public class JAXBUtil<T> {
- @SuppressWarnings("unchecked")
- public T unmarshal(Class<T> clazz, InputStream is) throws JAXBException {
- JAXBContext context = JAXBContext.newInstance(clazz);
- Unmarshaller un = context.createUnmarshaller();
- return (T) un.unmarshal(is);
- }
- public T unmarshal(Class<T> clazz, File file) throws JAXBException, FileNotFoundException {
- return unmarshal(clazz,new FileInputStream(file));
- }
- public void marshal(T element,OutputStream os) throws JAXBException{
- JAXBContext jc = JAXBContext.newInstance(element.getClass());
- Marshaller m = jc.createMarshaller();
- m.marshal(element, os);
- }
- public void marshal(T element, File output) throws FileNotFoundException, JAXBException{
- marshal(element,new FileOutputStream(output));
- }
- }
this is the simple util that packaging the JAXB operator.
then we can use it simplely.
1. we just export simple JODO to xml
- package ycl.learn.xml.jaxb;
- import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement
- public class EmployeeDO {
- private int id;
- private String gender;
- private int age;
- private String name;
- private String role;
- private String password;
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- public String getRole() {
- return role;
- }
- public void setRole(String role) {
- this.role = role;
- }
- @Override
- public String toString() {
- return "ID = " + id + " NAME=" + name + " AGE=" + age + " GENDER="
- + gender + " ROLE=" + role + " PASSWORD=" + password;
- }
- }
we must add @XmlRootElement to point this object is the root object for export.
- package ycl.learn.xml.jaxb;
- import java.io.File;
- import java.io.FileNotFoundException;
- import javax.xml.bind.JAXBException;
- public class JAXBUtilTest {
- private static final String FILE_NAME = "jaxb-emp-jaxbutil.xml";
- /**
- * @param args
- * @throws JAXBException
- * @throws FileNotFoundException
- */
- public static void main(String[] args) throws FileNotFoundException, JAXBException {
- // TODO Auto-generated method stub
- EmployeeDO emp = new EmployeeDO();
- emp.setId(1);
- emp.setAge(25);
- emp.setName("Pankaj");
- emp.setGender("Male");
- emp.setRole("Developer");
- emp.setPassword("sensitive");
- JAXBUtil<EmployeeDO> ju = new JAXBUtil<EmployeeDO>();
- ju.marshal(emp, new File(FILE_NAME));
- System.out.println("generator success");
- EmployeeDO empant = ju.unmarshal(EmployeeDO.class, new File(FILE_NAME));
- System.out.println("reader success");
- System.out.println(empant);
- }
- }
we can easily use JAXBUtil to marshal Object to file.
we can also easily use JAXBUtil to unmarchal File to Object.
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <employeeDO>
- <age>25</age>
- <gender>Male</gender>
- <id>1</id>
- <name>Pankaj</name>
- <password>sensitive</password>
- <role>Developer</role>
- </employeeDO>
If you review this code carefully, you will find the default root element name is the Object's name with first letter is lowercase.
the element under the root element is the attribute of the object.
Q1: can i change the Element Name, to generator Xml
- package ycl.learn.xml.jaxb;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement(name="content")
- public class EmployeeDO {
- private int id;
- private String gender;
- private int age;
- private String name;
- private String role;
- private String password;
- @XmlElement(name="pwd")
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- public String getRole() {
- return role;
- }
- public void setRole(String role) {
- this.role = role;
- }
- @Override
- public String toString() {
- return "ID = " + id + " NAME=" + name + " AGE=" + age + " GENDER="
- + gender + " ROLE=" + role + " PASSWORD=" + password;
- }
- }
we just need to set the @XmlRootElement or @XmlElement's name is ok.then the xml content is
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <content>
- <age>25</age>
- <gender>Male</gender>
- <id>1</id>
- <name>Pankaj</name>
- <pwd>sensitive</pwd>
- <role>Developer</role>
- </content>
Q2: can i point that some attribute of Object i don't want to export
- package ycl.learn.xml.jaxb;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- import javax.xml.bind.annotation.XmlTransient;
- @XmlRootElement(name="content")
- public class EmployeeDO {
- private int id;
- private String gender;
- private int age;
- private String name;
- private String role;
- private String password;
- @XmlElement(name="pwd")
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- @XmlTransient
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- public String getRole() {
- return role;
- }
- public void setRole(String role) {
- this.role = role;
- }
- @Override
- public String toString() {
- return "ID = " + id + " NAME=" + name + " AGE=" + age + " GENDER="
- + gender + " ROLE=" + role + " PASSWORD=" + password;
- }
- }
you can add @XmlTransient before the getMethod, then this attribute won't be export.
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <content>
- <age>25</age>
- <gender>Male</gender>
- <name>Pankaj</name>
- <pwd>sensitive</pwd>
- <role>Developer</role>
- </content>
Q3: can i export the attribute of Object as attribute, not Element of xml, and change the attribute name
- @XmlAttribute(name="agefather")
- public int getAge() {
- return age;
- }
very easily to change sub element to attribute.
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <content agefather="25">
- <gender>Male</gender>
- <name>Pankaj</name>
- <pwd>sensitive</pwd>
- <role>Developer</role>
- </content>
Q4: i want to export the xml element as my order
- @XmlRootElement(name="content")
- @XmlType(propOrder={"gender","age","name","role","password"})
- public class EmployeeDO
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <content agefather="25">
- <gender>Male</gender>
- <name>Pankaj</name>
- <role>Developer</role>
- <pwd>sensitive</pwd>
- </content>
you can see this element is ordered by our defined.
Q5: i want to export list of Objects
- @XmlElementWrapper(name="employees")
- @XmlElement(name="employee")
- public List<Employee> getEmployees() {
- return employees;
- }
- <employees>
- <employee>
- <age>25</age>
- <gender>GGGGGG</gender>
- <id>1</id>
- <name>Pankaj</name>
- <password>sensitive</password>
- <role>Developer</role>
- <family></family>
- </employee>
- <employee>
- <age>25</age>
- <gender>GGGGGGG</gender>
- <id>1</id>
- <name>Pankaj</name>
- <password>sensitive</password>
- <role>Developer</role>
- <family></family>
- </employee>
- </employees>
Q5: i want to export list of Objects in other Object
- [ClassA]
- public Family getFamily() {
- return family;
- }
- public class Family {
- private List<Employee> employees;
- @XmlElement(name="employee")
- public List<Employee> getEmployees() {
- return employees;
- }
- public void setEmployees(List<Employee> employees) {
- this.employees = employees;
- }
- }
- <family>
- <employee>
- <age>25</age>
- <gender>LLLLLLL</gender>
- <id>1</id>
- <name>Pankaj</name>
- <password>sensitive</password>
- <role>Developer</role>
- <family></family>
- </employee>
- <employee>
- <age>25</age>
- <gender>Male</gender>
- <id>1</id>
- <name>Pankaj</name>
- <password>sensitive</password>
- <role>Developer</role>
- <family></family>
- </employee>
- </family>
oh, you just don't to defined family, because it is the element of the object, default define is ok.
the employee is multiple in family, you just define the @XmlElement empoyee is ok,and this will be auto add to list
so this is you can think of the four questions, and i can't think other situations, and i think this four points can resolve all problems that we encountered, we can easily change xml Element name, Element attribute, Element order, that's cool.