加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

JAXBContext用于xml与Bean转换

发布时间:2020-12-16 08:04:37 所属栏目:百科 来源:网络整理
导读:Java中提供一套用于XML与Bean转换的工具javax.xml.bind.JAXBContext 先说结论,在定义Bean时,要保证其默认无参的构造函数不能被覆盖。(即如果定义了其它构造函数,则默认无参构造函数要显示定义) JAXB实现对象与xml互转注解: 1.@XmlRootElement,用于类

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));
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读