java 中jaxb实现对象到xml互相转换

jaxb是jdk自带的一种实现java对象与xml文件互相转化;以及生成自动生成xsd文件。
JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分,不需要引入其他的jar包。
主要接口:
JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。
Marshaller接口,将Java对象序列化为XML数据。
Unmarshaller接口,将XML数据反序列化为Java对象。

常用注解
@XmlRootElement 将一个Java类映射为一段XML的根节点

参数:name 定义这个根节点的名称

  namespace    定义这个根节点命名空间

@XmlAccessorType 定义映射这个类中的何种类型需要映射到XML。可接收四个参数,分别是:

  XmlAccessType.FIELD:映射这个类中的所有字段到XML

  XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML

  XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)

  XmlAccessType.NONE:不映射

@XmlElement 指定一个字段或get/set方法映射到XML的节点。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一个没有get/set方法的字段上标注此注解,即可将该字段映射到XML。

参数:defaultValue 指定节点默认值

     name             指定节点名称

     namespace    指定节点命名空间

     required         是否必须(默认为false)

     nillable           该字段是否包含 nillable="true" 属性(默认为false)

     type               定义该字段或属性的关联类型

@XmlAttribute 指定一个字段或get/set方法映射到XML的属性。

参数:name 指定属性名称

     namespace    指定属性命名空间

     required         是否必须(默认为false)

@XmlTransient 定义某一字段或属性不需要被映射为XML。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。

@XmlType 定义映射的一些相关规则

参数:propOrder 指定映射XML时的节点顺序

     factoryClass     指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身

     factoryMethod  指定工厂类的工厂方法

     name               定义XML Schema中type的名称

     namespace      指定Schema中的命名空间

@XmlElementWrapper 为数组元素或集合元素定义一个父节点。如,类中有一元素为List items,若不加此注解,该元素将被映射为

<items>...</items>

<items>...</items>

这种形式,此注解可将这个元素进行包装,如:

@XmlElementWrapper(name="items") 
@XmlElement(name="item") 
public List items;

将会生成这样的XML样式:

<items>

    <item>...</item>

    <item>...</item>

</items>

@XmlJavaTypeAdapter 自定义某一字段或属性映射到XML的适配器。如,类中包含一个接口,我们可以定义一个适配器(继承自javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。

@XmlSchema 配置整个包的namespace,这个注解需放在package-info.java文件中。


JAXB2就是JAVA和XML相互转换的工具。

JAXB2体系包括Schema生成器、Schema编译器及运行时绑定框架。

它比较常用的7个注释:@XmlAttribute、@XmlElement、@XmlElementWrapper、@XmlRootElement、@XmlAccessorType、@XmlType与@XmlSchema。

(1)@XmlElement

java类的域变量。当类为public,或实现get/set,无须标注@XmlElement注释,也会根据默认值实现转化。有name、 namespace属性。name是输出xml的名。{nillable}?属性,为false,该域变量为空时不输出。required属性,为true表示该域变量必须存在。

(2)@XmlAttribute

(3)@XmlElementWrapper

对于collection、list、map等,用@XmlElementWrapper注释才可以实现将所有集合无素输出。

eg

@XmlElementWrapper

@XmlElement(name=”item”)———————–每个子元素的名

private List items;

(4)@XmlRootElement

根结点。

(5)@XmlAccessorType

注释java类。有关于什么类型的变量输出。

(6)@XmlType

注释java类。在列集过程中,改变域变量输出顺序。(默认字母顺序);在反列集过程中利用@XmlType注释可以设置构造该java对象的方式。

(7)@XmlSchema

用来注释java包。通过它可以配置整个包的namespace。由于它出现在import前,所以需要完整的类路径。

demo:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public final class JAXBCache {
    private static final JAXBCache instance = new JAXBCache();
    private final ConcurrentMap<String, JAXBContext> contextCache = new ConcurrentHashMap<String, JAXBContext>();
    private JAXBCache() {
    }
    public static JAXBCache instance() {
        return instance;
    }
    JAXBContext getJAXBContext(Class<?> clazz) throws JAXBException {
        JAXBContext context = contextCache.get(clazz.getName());
        if ( context == null )
        {
            context = JAXBContext.newInstance(clazz);
            contextCache.putIfAbsent(clazz.getName(), context);
        }
        return context;
    }
}
import javax.xml.bind.JAXBContext;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;

public class JAXBExportSchema {
    public static void main(String[] args) {
        JAXBContext jct;
        try
        {
            jct = JAXBContext.newInstance(User.class);
            jct.generateSchema(new Resolver());
        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
        }
    }
}
class Resolver extends SchemaOutputResolver {
    @Override
    public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
        File file = new File("d:\\", suggestedFileName);
        StreamResult result = new StreamResult(file);
        result.setSystemId(file.toURI().toURL().toString());
        return result;
    }
}

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.io.IOUtils;
/**
 * marshal对象和unmarshal对象都是由JAXBContext创建.所以一开始需要初始化JAXBContext.
 * @author Credo
 */
public class JAXBUtil {
    /**
     * 生成xml文件的二进制数据
     * @param obj 对象
     */
    public static byte[] marshal(Object obj) throws JAXBException {
        JAXBContext context = JAXBCache.instance().getJAXBContext(obj.getClass());
        Marshaller m = context.createMarshaller();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.setProperty(Marshaller.JAXB_ENCODING,"utf-8");
        m.marshal(obj, outputStream);
        byte[] result = outputStream.toByteArray();
        return result;
    }
    /**
     * @param data xml stream
     * @param classe 类
     * @return jaxb生成xml的java 类对象
     */
    public static Object unmarshal(byte[] data, Class<?> classe) throws JAXBException {
        JAXBContext context = JAXBCache.instance().getJAXBContext(classe);
        Unmarshaller m = context.createUnmarshaller();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
        Object obj = m.unmarshal(inputStream);
        return obj;
    }
    /**
     *
     * @param classe 类
     * @return jaxb生成xml的java 类对象
     */
    public static Object unmarshal(InputStream in, Class<?> classe) throws JAXBException, IOException {
        JAXBContext context = JAXBCache.instance().getJAXBContext(classe);
        byte[] data = IOUtils.toByteArray(in);
        Unmarshaller m = context.createUnmarshaller();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
        Object obj = m.unmarshal(inputStream);
        return obj;
    }
    public static void main(String[] args) throws JAXBException {
        User userinfo = new User();
        userinfo.setId(Long.valueOf(11));
        List<OverInfo> list = new ArrayList<OverInfo>();
        OverInfo e = new OverInfo();
        e.setStage("小学");
        e.setStart(new Date());
        e.setEnd(new Date());
        list.add(e);
        OverInfo e1 = new OverInfo();
        e1.setStage("中学");
        list.add(e1);
        userinfo.setOverinfos(list);
        byte[] b = JAXBUtil.marshal(userinfo);
        System.out.println(new String(b));
        userinfo = (User) JAXBUtil.unmarshal(b, User.class);
        System.out.println(userinfo.getOverinfos().get(0).getStage());
    }
}
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;

/**
 * jaxbtest-overinfo
 *
 * @author
 * @create 2017-11-01 14:40
 **/
@XmlType
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class OverInfo {
    private String stage;
    @XmlJavaTypeAdapter(value = DateAdapter.class)
    private Date start;
    @XmlJavaTypeAdapter(value = DateAdapter.class)
    private Date end;

    public String getStage() {
        return stage;
    }

    public void setStage(String stage) {
        this.stage = stage;
    }

    public Date getStart() {
        return start;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    public Date getEnd() {
        return end;
    }

    public void setEnd(Date end) {
        this.end = end;
    }
}
import javax.xml.bind.annotation.*;
import java.util.List;

/**
 * jaxbTest-user
 *
 * @author alex
 * @create 2017-11-01 14:26
 **/
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class User {
    private static final long serialVersionUID = 7870351249722416047L;
    private Long id;
    private String name;
    private String job;
    @XmlElementWrapper(name ="overinfos")
    @XmlElements(value={@XmlElement(name="overinfo",type=OverInfo.class)})
    private List<OverInfo>  overinfos;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public List<OverInfo> getOverinfos() {
        return overinfos;
    }

    public void setOverinfos(List<OverInfo> overinfos) {
        this.overinfos = overinfos;
    }



}
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * jaxbtest-dateAdpetr
 *
 * @author
 * @create 2017-11-01 14:54
 **/
public class DateAdapter  extends XmlAdapter<String , Date>{
    private static String pattern = "yyyy-MM-dd HH:mm:ss";
    private SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    protected DateAdapter() {
        super();
    }

    @Override
    public Date unmarshal(String v) throws Exception {
        return sdf.parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        return sdf.format(v);
    }
}

运行结果
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值