在Rest服务调用中应用JAXB来实现XML与对象之间的转换

    技术2022-05-20  36

    最近在用HttpClien来调用Rest服务,在其中要用到XML与java对象之间的转换,发现用JAXB非常方便。现整理如下。具体应用例子转帖自http://terrencexu.javaeye.com/blog/702089

     

    在java开发中使用XML几乎是每个程序员都会碰到的,目前可供我们选择的库也有很多,包括,dom4j, jaxen,  SAX等等,本文将介绍如何使用JAXB进行Object-XML mapping.

     

    JAXB目前已经集成到了JDK6中,但还是推荐下载使用最新版的jaxb库, https://jaxb.dev.java.net/,本文下载的是2.2.3,下载安装后将安装后的lib目录中的jaxb-impl.jar拷贝到项目的lib目录中,引用即可,即可使用该下载的JAXB包。

     

    从JAXB2.0开始,可以通过使用annotation进行Object-XMl mapping。

     

    本文将通过以下步骤演示如何使用JAXB annotation绑定使用了namespace的XML文件

    1. 创建Employees.java和Employee.java

    2. 创建package-info.java和jaxb.index文件

    3. 创建XMLParser.java封装marshal/unmarshal操作

    4. 创建employees.xml文件

    5. 创建Test.java运行测试

    6. 运行结果:

     

    1. 创建Employees.java和Employee.java

    Java代码

    package com.javaeye.terrencexu.jaxb;  

    import java.util.ArrayList;  

    import java.util.List;  

    import javax.xml.bind.annotation.XmlElement;  

    import javax.xml.bind.annotation.XmlRootElement;  

     

    @XmlRootElement(name = "employees")  

    public class Employees {    

     

        private List<Employee> employees;  

     

        public Employees() {  

            employees = new ArrayList<Employee>();  

        }  

     

        @XmlElement(name = "employee" , namespace=NameSpace.ADMIN_URI)  

        public List<Employee> getEmployees() {

            return employees;

        }

     

        public void setEmployees(List<Employee> employees) {

            this.employees = employees;

        }

     

        public void addEmployee(Employee employee) {  

            employees.add(employee);  

        }    

     

     

     

    Java代码

    package com.javaeye.terrencexu.jaxb;  

    import javax.xml.bind.annotation.XmlElement;  

     

    public class Employee {  

     

        private String userId;  

        private String password;  

        private String name;  

        private int age;  

        private String gender;  

     

        public Employee() {  

        }  

     

        public Employee(String userId, String psw, String name, int age, Gender gender) {  

            this.userId = userId;  

            this.password = psw;  

            this.name = name;  

            this.age = age;  

            this.gender = gender.getValue();  

        }  

     

         @XmlElement(name = "userId", namespace=NameSpace.ADMIN_URI)  

         public String getUserId() {

             return userId;

          }

     

          public void setUserId(String userId) {

             this.userId = userId;

    }

     

    @XmlElement(name = "password", namespace=NameSpace.ADMIN_URI) 

    public String getPassword() {

    return password;

    }

     

    public void setPassword(String password) {

    this.password = password;

    }

     

    @XmlElement(name = "name", namespace=NameSpace.ADMIN_URI)  

    public String getName() {

    return name;

    }

     

    public void setName(String name) {

    this.name = name;

    }

     

    @XmlElement(name = "age", namespace=NameSpace.ADMIN_URI)

    public int getAge() {

    return age;

    }

     

    public void setAge(int age) {

    this.age = age;

    }

     

    @XmlElement(name = "gender", namespace=NameSpace.ADMIN_URI)  

    public String getGender() {

    return gender;

    }

     

    public void setGender(String gender) {

    this.gender = gender;

    }

     

    }  

    Java代码 package com.javaeye.terrencexu.jaxb; public class NameSpace { public static final String ADMIN_PREFIX = "admin";       public static final String ADMIN_URI = "http://www.company.com/management/employees/admin";   } Java代码 package com.javaeye.terrencexu.jaxb;      public enum Gender {          MALE("Male"),       FEMALE("Female");              private String value;              private Gender(String value) {           this.value = value;       }              public String getValue() {           return this.value;       }          } 

    2. 创建package-info.java和jaxb.index文件

    创建package-info.java文件是为了注册xmlns, 将该文件放在当前source code的package下面,如果不使用namespace可以不创建该文件

     

    @XmlSchema(  

    xmlns={  

            @XmlNs(prefix=NameSpace.ADMIN_PREFIX, namespaceURI=NameSpace.ADMIN_URI)  

    }  

    )  

    package com.javaeye.terrencexu.jaxb;  

     

    import javax.xml.bind.annotation.XmlNs;

    import javax.xml.bind.annotation.XmlSchema;

     创建jaxb.index注册Employees, Employee,如果不使用包级context,可以不创建该文件

     

    Employees  

    Employee

     

     

     

    3. 创建XMLParser.java封装marshal/unmarshal操作

     

    package com.javaeye.terrencexu.jaxb;

    import java.io.InputStream;

    import java.io.StringWriter;

    import javax.xml.bind.JAXBContext;

    import javax.xml.bind.JAXBException;

    import javax.xml.bind.Marshaller;

    import javax.xml.bind.Unmarshaller;

     

    public final class XMLParser {

    private static final String PACKAGE_NAME = "com.javaeye.terrencexu.jaxb";

    private JAXBContext jc;

     

    public XMLParser() {

    try {

    jc = JAXBContext.newInstance(PACKAGE_NAME, getClass().getClassLoader());

    } catch (JAXBException e) {

    e.printStackTrace();

    }

    }

     

    public Object unmarshal(InputStream xml,Class objclass) {

    Object obj = null;

    try {

    Unmarshaller u = jc.createUnmarshaller();

    Reader reader = new InputStreamReader(xml,"utf-8");

    StreamSource source = new StreamSource(reader);

    obj = u.unmarshal(source,objclass).getValue();

    } catch (JAXBException e) {

     e.printStackTrace();

    throw new RuntimeException(

    "Can't unmarshal the XML file, error message: " + e.getMessage());

    }catch(UnSupportedEncodingException e){

     e.printStackTrace();} 

    return obj;

    }

     

    public String marshal(Object obj) {

    String result = null;

    try {

    Marshaller m = jc.createMarshaller();

    StringWriter writer = new StringWriter();

    m.marshal(obj, writer);

    result = writer.toString();

    } catch (JAXBException e) {

    throw new RuntimeException(

    "Can't marshal the XML file, error message: " + e.getMessage());

    }

    return result;

    }

     

    }

     

    4. 创建employees.xml文件

     

    <?xml version="1.0" encoding="utf-8" ?>  

    <employees xmlns:admin="http://www.company.com/management/employees/admin">  

        <admin:employee>  

            <admin:userId>johnsmith@company.com</admin:userId>  

            <admin:password>abc123_</admin:password>  

            <admin:name>John Smith</admin:name>  

            <admin:age>24</admin:age>  

            <admin:gender>Male</admin:gender>  

        </admin:employee>  

        <admin:employee>  

            <admin:userId>christinechen@company.com</admin:userId>  

            <admin:password>123456</admin:password>  

            <admin:name>Christine Chen</admin:name>  

            <admin:age>27</admin:age>  

            <admin:gender>Female</admin:gender>  

        </admin:employee>  

    </employees> 

    这是一个很普通的xml文件,主要是为了后面的测试,用于展示组织内部的成员(employee)状况,这里有一点需要注意的是使用了namespace,这也是本文将要演示的重点。

     

    5.创建Test.java运行测试

    package com.javaeye.terrencexu.jaxb;  

     

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.FileNotFoundException;

    import java.util.List;

     

    public class Test {  

        public static void main(String[] args) throws FileNotFoundException {  

            testUnmarshal();  

            testMarshal();  

        }  

     

        public static void testUnmarshal() throws FileNotFoundException {  

         XMLParser xMLParser = new XMLParser();

            Employees employees = (Employees) xMLParser.unmarshal(  

              new FileInputStream(new File("D:/eclipse 3.6/workspace/JAXB-test/src/xml/employees.xml"),Employees.class));  

     

            List<Employee> employeeList = employees.getEmployees();  

     

            if (employeeList != null && employeeList.size() > 0) {  

                for (Employee employee : employeeList) {  

                    StringBuilder builder = new StringBuilder();  

                    builder.append("[UserID: ").append(employee.getUserId()).append(", ")  

                           .append("Password: ").append(employee.getPassword()).append(", ")  

                           .append("Name: ").append(employee.getName()).append(", ")  

                           .append("Age: ").append(employee.getAge()).append(", ")  

                           .append("Gender").append(employee.getGender()).append("]");  

     

                    System.out.println(builder.toString());  

                }  

            }  

     

        }  

     

        public static void testMarshal() {  

            Employees employees = new Employees();  

            employees.addEmployee(new Employee("johnsmith@company.com", "abc123_", "John Smith", 24, Gender.MALE));  

            employees.addEmployee(new Employee("christinechen@company.com", "123456", "Christine Chen", 27, Gender.FEMALE));  

            XMLParser xMLParser = new XMLParser();  

            String result = xMLParser.marshal(employees);  

            System.out.println(result);  

        }  

    }  

     

    6. 运行结果:

     

     

    [UserID: johnsmith@company.com, Password: abc123_, Name: John Smith, Age: 24, GenderMale]

    [UserID: christinechen@company.com, Password: 123456, Name: Christine Chen, Age: 27, GenderFemale]

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

    <employees xmlns:admin="http://www.company.com/management/employees/admin">

    <admin:employee>

    <admin:userId>johnsmith@company.com</admin:userId>

    <admin:password>abc123_</admin:password>

    <admin:name>John Smith</admin:name>

    <admin:age>24</admin:age>

    <admin:gender>Male</admin:gender>

    </admin:employee>

    <admin:employee>

    <admin:userId>christinechen@company.com</admin:userId>

    <admin:password>123456</admin:password>

    <admin:name>Christine Chen</admin:name>

    <admin:age>27</admin:age>

    <admin:gender>Female</admin:gender>

    </admin:employee></employees>

     

     

     


    最新回复(0)