JAXB

   JAXB(Java API for XML Binding),提供了一个快速便捷的方式将Java对象与XML进行转换。在JAX-WS(Java的WebService规范之一)中,JDK1.6 自带的版本JAX-WS2.1,其底层支持就是JAXB。

   JAXB 可以实现Java对象与XML的相互转换,在JAXB中,将一个Java对象转换为XML的过程称之为Marshal,将XML转换为Java对象的过程称之为UnMarshal。我们可以通过在 Java 类中标注注解的方式将一个Java对象绑定到一段XML,也就是说,在Java类中标注一些注解,这些注解定义了如何将这个类转换为XML,怎么转换,以及一段XML如何被解析成这个类所定义的对象;也可以使用JAXB的XJC工具,通过定义schema的方式实现Java对象与XML的绑定。

   下面来了解一下如何通过标注注解来完成 Marshal 和 UnMarshal 的过程。

首先看个小例子:

定义一个java类

 1 package jaxb;
 2 
 3 import javax.xml.bind.annotation.XmlElement;
 4 import javax.xml.bind.annotation.XmlRootElement;
 5 import javax.xml.bind.annotation.XmlType;
 6 
 7 @XmlType(name = "", propOrder = {
 8   "name",
 9    "age",
10    "id"
11   })
12 @XmlRootElement(name="Student")
13 public class Student
14 {
15     @XmlElement(name="ID")
16     public int id = 1;
17     @XmlElement(name="Name")
18     public String name = "ldd";
19     @XmlElement(name="Age")
20     public int age = 18;
21     @Override
22     public String toString()
23     {
24         return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
25     }
26 }

Java To XML(Marshal)

 1 package jaxb;
 2 
 3 import javax.xml.bind.JAXBContext;
 4 import javax.xml.bind.JAXBException;
 5 import javax.xml.bind.Marshaller;
 6 
 7 public class JavaToXML
 8 {
 9     public static void main(String[] args) throws JAXBException
10     {
11         JAXBContext context = JAXBContext.newInstance(Student.class);
12         Marshaller marshaller = context.createMarshaller();
13         marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");//编码格式 
14         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否格式化生成的xml串  
15         marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);//是否省略xml头信息(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)  
16         Student student = new Student();
17         marshaller.marshal(student, System.out);
18     }
19 }

输出结果如下:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Student>
    <Name>ldd</Name>
    <Age>18</Age>
    <ID>1</ID>
</Student>

XML To Java(UnMarshal)

 1 package jaxb;
 2 
 3 import java.io.File;
 4 
 5 import javax.xml.bind.JAXBContext;
 6 import javax.xml.bind.JAXBException;
 7 import javax.xml.bind.Unmarshaller;
 8 
 9 
10 public class XmlToJava
11 {
12     public static void main(String[] args) throws JAXBException
13     {
14         JAXBContext context = JAXBContext.newInstance(Student.class);
15         Unmarshaller unmarshaller = context.createUnmarshaller();
16         File file = new File("src/main/java/student.xml");
17         Student student = (Student) unmarshaller.unmarshal(file);
18         System.out.println(student);
19     }
20 }

 如果是一些复杂点的list集合之类的

如果我们预期的xml是这样的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<userinfo>
    <list name="user info">
        <users id="1">
            <name>ldd1</name>
            <sex>1</sex>
        </users>
        <users id="2">
            <name>ldd2</name>
            <sex>2</sex>
        </users>
    </list>
</userinfo>

首先,定义一个实体类 User

package userdemo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;

@XmlAccessorType(XmlAccessType.FIELD)
public class User
{
    @XmlAttribute
    private int id;
    private String name;
    private int sex;
    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 getSex()
    {
        return sex;
    }
    public void setSex(int sex)
    {
        this.sex = sex;
    }
    
}
特别说明: 如果 @XmlAccessorType()的类型为 XmlAccessType.FIELD,那么@XmlAttribute和@XmlElement的注解就可以放在属性上,否则只能放在get方法上,不然会报错。
 下面再定义一个 Users类,目的是为了封装user的list
package userdemo;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@XmlAccessorType(XmlAccessType.FIELD)
public class Users
{
    private List<User> users;
    @XmlAttribute
    private String name;
    public List<User> getUsers()
    {
        return users;
    }
    public void setUsers(List<User> users)
    {
        this.users = users;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    
    
}

 

接下来再定义一个UserInfo实体类,继续包装
package userdemo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="userinfo")
public class UserInfo
{
    @XmlElement(name="list")
    private Users users;

    public Users getUsers()
    {
        return users;
    }

    public void setUsers(Users users)
    {
        this.users = users;
    }
    
}

准备工作已做好,可以进行测试了

package userdemo;

import java.util.ArrayList;
import java.util.List;

import utils.JaxbUtil;

public class UserDemo
{
public static void main(String[] args)
{
    UserInfo userInfo = new UserInfo();
    Users users = new Users();
    User user = new User();
    user.setId(1);
    user.setName("ldd1");
    user.setSex(1);
    
    User user2 = new User();
    user2.setId(2);
    user2.setName("ldd2");
    user2.setSex(2);
    
    List<User> uList = new ArrayList<User>();
    uList.add(user);
    uList.add(user2);
    users.setUsers(uList);
    users.setName("user info");
    
    userInfo.setUsers(users);
    String string = JaxbUtil.convertToXml(userInfo);
    System.out.println(string);
}
}
JaxbUtil类
package utils;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class JaxbUtil
{
    /**
     * JavaBean转换成xml
     * 默认编码UTF-8
     * @param obj
     * @param writer
     * @return 
     */
    public static String convertToXml(Object obj) 
    {
        return convertToXml(obj, "UTF-8");
    }
    /**
     * JavaBean转换成xml
     * @param obj
     * @param encoding 
     * @return 
     */
    public static String convertToXml(Object obj, String encoding) {
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //xml格式
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); //编码

            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * xml转换成JavaBean
     * @param xml
     * @param c
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T converyToJavaBean(String xml, Class<T> c) {
        T t = null;
        try {
            JAXBContext context = JAXBContext.newInstance(c);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return t;
    }
}

当然,其实也并不用包装这么层。可以用@XmlElementWrraper注解就可以在某个属性标签外面包裹一层标签。

其实Marshal 和 UnMarshal的过程并不复杂,只需要从JAXBContext中获得Marshaller或Unmarshaller对象,就可以让JAXB帮我们来进行转换了。我们需要操作的主要内容是定义一个规则,告诉JAXB如何将一个类、按照什么样的格式转换为XML,此处暂略过JAXB中主要的一些注解。可自行百度。

由于现在还对这个并不太深入理解,也不知道在合理性上如何,但是实践中还是没啥问题的。

 

posted @ 2016-01-19 16:25  羊皮纸月亮  阅读(...)  评论(... 编辑 收藏