JAXBContext用于xml与Bean转换

Java中提供一套用于XML与Bean转换的工具javax.xml.bind.JAXBContext

先说结论:

在定义Bean时,要保证其默认无参的构造函数不能被覆盖(即当定义有参构造函数后默认无参构造函数需要显示声明定义)

 

JAXB实现对象与xml互转注解:


1.@XmlRootElement,用于类级别的注解,对应xml的跟元素。通过name属性定义这个根节点的名称。


2.@XmlAccessorType,定义映射这个类中的何种类型都需要映射到xml。(如果不存在@XmlAccessorType,默认使用XmlAccessType.PUBLIC_MEMBER注解)


  参数:XmlAccessType.FIELD: java对象中的所有成员变量。


  XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量。


  XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量。


  XmlAccessType.NONE: java对象的所有属性都不映射为xml的元素。


3.@XmlAttribute,用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。


4.@XmlElement,指定一个字段或get/set方法映射到xml的节点。通过name属性定义这个根节点的名称。


5.@XmlElementWrapper,为数组或集合定义一个父节点。通过name属性定义这个父节点的名称

 

 

package com.zte.sunquan.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by xxx on 2017/10/20.
 */
@XmlRootElement(name = "person")
public class Person {
    @XmlAttribute(name = "name")
    public String name;
    @XmlAttribute(name = "age")
    public int age;


    public Person() {
    }

    private List<String> hobby=new ArrayList<>();

    public Person(String name) {
        this.name = name;
    }

    @XmlElementWrapper(name = "hobbys")
    @XmlElement(name = "hobby")
    public List<String> getHobby() {
        return hobby;
    }

    public void addHobby(String hobby) {
        this.hobby.add(hobby);
    }
}


上面的Bean,对于无参构造函数显示增加了定义

 

在源码com.sun.xml.bind.v2.model.impl.ClassInfoImpl.java构造函数中,会对类是否有默认构造函数进行校验

 

        // the class must have the default constructor
        if (!hasFactoryConstructor(t)){
            if(!nav().hasDefaultConstructor(clazz)){
                if(nav().isInnerClass(clazz)) {
                    builder.reportError(new IllegalAnnotationException(
                        Messages.CANT_HANDLE_INNER_CLASS.format(nav().getClassName(clazz)), this ));
                } else if (elementName != null) {
                    builder.reportError(new IllegalAnnotationException(
                        Messages.NO_DEFAULT_CONSTRUCTOR.format(nav().getClassName(clazz)), this ));
                }
            }
        }


测试脚本:

 

 

package com.zte.sunquan.jaxb;

import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.dom.DOMResult;
import java.io.StringReader;
import java.io.StringWriter;

import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;

/**
 * Created by xxx on 2017/10/20.
 */
public class PersonTest {
    private Person person;
    int age = 29;
    String name = "Foo";
    String hobby = "singing";

    @Before
    public void init() {
        person = new Person("xy");
        person.name = name;
        person.age = age;
        person.addHobby(hobby);

    }

    @Test
    public void testMarshallerDocument() throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(person.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//格式化xml输出
        DOMResult res = new DOMResult();
        marshaller.marshal(person, res);
        Element doc = ((Document) res.getNode()).getDocumentElement();
        assertEquals(name, doc.getAttribute("name"));
        assertEquals(age, Integer.parseInt(doc.getAttribute("age")));
        //((Document) res.getNode()).getDocumentElement()
        NodeList hobbys = doc.getChildNodes();
        assertEquals(hobby, hobbys.item(0).getTextContent());
    }

    @Test
    public void testMarshallerString() throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(person.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//格式化xml输出

        StringWriter writer = new StringWriter();
        marshaller.marshal(person, writer);
        String outString = writer.toString();
        System.out.println(outString);
        assertTrue(outString.contains("</person"));
    }

    @Test
    public void testUnMarshaller() throws JAXBException {

        String outString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
                "<person name=\"Foo\" age=\"29\">\n" +
                "    <hobbys>\n" +
                "        <hobby>singing</hobby>\n" +
                "    </hobbys>\n" +
                "</person>";

        JAXBContext context = JAXBContext.newInstance(Person.class, Person.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        StringReader reader = new StringReader(outString);
        Person reciever = (Person) unmarshaller.unmarshal(reader);
        assertEquals(name, reciever.name);
        assertEquals(age, reciever.age);
        assertEquals(hobby, reciever.getHobby().get(0));
    }
}

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值