【java系列】使用JAXB实现java对象和XML的转换

JAXB

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。

核心类

JAXBContext:

  • Jaxb的上下文,通过这个对象我们能拿到另外两个核心对象Unmarshaller(用于解析xml)和Marshaller (生成xml)JAXBContext通常使用它的静态方法newInstance(Class className)来获得对象

Unmarshaller

  • 用于解析xml 通过JAXBContext的createUnmarshaller方法获得到

Marshaller

  • 用于生成xml 通过JAXBContext的createMarshaller方法获得到

核心注解

@XmlRootElement :

xml 文件的根元素

@XmlAccessorType:

包和类级别的注解。javaEE的API对该注解的解释是:控制字段是否被默认序列化。

  • PROPERTY:自动绑定getter/setter方法的属性。
  • FIELD:自动绑定非静态、非瞬态字段。
  • PUBLIC_MEMBER(默认):相当于PROPERTY+FIELD。
  • NONE:都不绑定。

注意:

JAXB绑定xml有三种方式:
1.字段绑定(需要public修饰)。
2.getter/setter的属性绑定(需要public修饰)。
3.被@XmlElement注解修饰的字段或者getter/setter方法(四种修饰符都可以)。

注意:方式3中优先绑定为@XmlElement的name属性,其次按照字段名或者getter/setter的属性名,且同一个属性的getter/setter只需要绑定一次。

如果说非要同时使用getter/setter和@XmlElement、字段和@XmlElement,又不想出现上面提示绑定两次的报错,这个时候就需要使用@XmlAccessorType,指定value为PROPERTY或者FIELD或者NONE。

@XmlElement:
  • @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。
@XmlAttribute:
  • @XmlAttribute將被序列化为xml节点中的属性

@XmlAttribute和@XmlElement的区别,就是一个为节点属性,一个为节点
image.png

@XmlTransient

类,字段,方法级别的注解。可使JAXB在映射xml元素时忽略被注解的类,字段,get/set对应字段。需要注意的是该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错。

java对象转xml

下面为使用案例

1、引入依赖

引入lombom和fastjson,方便转换

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.22</version>
        </dependency>

   <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
2、定义实体类
package xml;

import lombok.Data;

import javax.xml.bind.annotation.*;
//1、根节点
@XmlRootElement(name = "Person")
//控制是否序列化
@XmlAccessorType(XmlAccessType.FIELD)
// lombok中自动生成getter和setter方法
@Data
public class Person {

//生成节点
    @XmlElement(name = "NAME")
    private String name;
//节点属性
    @XmlAttribute(name = "SEX")
    private String sex;

    @XmlElement(name = "AGE")
    private Integer age;

    //子节点,是一个类
    @XmlElement
    private FamilyInfo familyInfo;

}

package xml;

import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@Data
//这里注意需要加上去,否则如果是默认的话,会产生错误
//
@XmlAccessorType(XmlAccessType.FIELD)
public class FamilyInfo {

    @XmlElement(name = "Father")
    private String father;
    @XmlElement(name = "Mother")
    private String mother;
}

3、测试方法
package xml;

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

public class JAXBTest {

    public static void main(String[] args) throws JAXBException {
        //java对象转xml
        testBeanToXml();

    }

//测试方法
    public static void testBeanToXml() throws JAXBException {
        Person person = new Person();
        person.setName("walker");
        person.setAge(18);
        person.setSex("男");

        FamilyInfo familyInfo = new FamilyInfo();
        familyInfo.setFather("walker_father");
        familyInfo.setMother("walker_mother");
        person.setFamilyInfo(familyInfo);

        JAXBContext context=null;
        StringWriter writer=null;

        //1、创建上下文
        context = JAXBContext.newInstance(Person.class);
        //2、创建Marshaller 这个是用于转换成xml的
        Marshaller marshaller = context.createMarshaller();
        //3、设置marshaller的属性
        //JAXB_FORMATTED_OUTPUT:格式化
        //JAXB_ENCODING:编码格式
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING,"utf8");
        //4、实例化StringWriter
        writer=new StringWriter();
        //5、将实体类读取到writer中
        marshaller.marshal(person,writer);
        //6、输出结果
        System.out.println(writer.toString());
    }
}

Marshaller的相关属性

JAXB_ENCODING:编码
JAXB_FORMATTED_OUTPUT

  • jaxb.formatted.output:值必须是 java.lang.Boolean
    此属性控制 Marshaller 是否使用换行和缩排对得到的 XML 数据进行格式化。此属性为 true 值表示可读性强的缩排 xml 数据,而属性值为 false 则表示未格式化的 xml 数据。如果未指定此属性,则 Marshaller 将该属性值默认为 false (未格式化)。

JAXB_SCHEMA_LOCATION:

JAXB_NO_NAMESPACE_SCHEMA_LOCATION:

JAXB_FRAGMENT:

public static final String JAXB_ENCODING =
        "jaxb.encoding";

    /**
     * The name of the property used to specify whether or not the marshalled
     * XML data is formatted with linefeeds and indentation.
     */
    public static final String JAXB_FORMATTED_OUTPUT =
        "jaxb.formatted.output";

    /**
     * The name of the property used to specify the xsi:schemaLocation
     * attribute value to place in the marshalled XML output.
     */
    public static final String JAXB_SCHEMA_LOCATION =
        "jaxb.schemaLocation";

    /**
     * The name of the property used to specify the
     * xsi:noNamespaceSchemaLocation attribute value to place in the marshalled
     * XML output.
     */
    public static final String JAXB_NO_NAMESPACE_SCHEMA_LOCATION =
        "jaxb.noNamespaceSchemaLocation";

    /**
     * The name of the property used to specify whether or not the marshaller
     * will generate document level events (ie calling startDocument or endDocument).
     */
    public static final String JAXB_FRAGMENT =
        "jaxb.fragment";
4、返回结果
<?xml version="1.0" encoding="utf8" standalone="yes"?>
<Person SEX="">
    <NAME>walker</NAME>
    <AGE>18</AGE>
    <familyInfo>
        <Father>walker_father</Father>
        <Mother>walker_mother</Mother>
    </familyInfo>
</Person>

可以发现使用@XmlAttribute生成的是属性,@XmlElement生成的是子节点

xml转bean

第1、2步和java对象转xml一样
3、测试方法
package xml;

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

public class JAXBTest {

    public static void main(String[] args) throws JAXBException {
        /**
        * xml字符串转java对象
        */
        xmlStrToBean();

    }


    public static void xmlStrToBean() throws JAXBException {
        String xmlStr="<?xml version=\"1.0\" encoding=\"utf8\" standalone=\"yes\"?>\n" +
                "<Person SEX=\"男\">\n" +
                "    <NAME>walker</NAME>\n" +
                "    <AGE>18</AGE>\n" +
                "    <familyInfo>\n" +
                "        <Father>walker_father</Father>\n" +
                "        <Mother>walker_mother</Mother>\n" +
                "    </familyInfo>\n" +
                "</Person>";

        JAXBContext context=null;
        StringReader reader=null;
        //1、创建context
        context=JAXBContext.newInstance(Person.class);
        //2、创建Unmarshaller
        Unmarshaller unmarshaller = context.createUnmarshaller();
        //3、实例化reader,将xml字符串放入参数
        reader=new StringReader(xmlStr);
        //4、使用unmarshaller.unmarshal 参数放入read
        Object res = unmarshaller.unmarshal(reader);
        //5、输出结果
        System.out.println(res);

    }

}

4、输出结果
Person(name=walker, sex=男, age=18, familyInfo=FamilyInfo(father=walker_father, mother=walker_mother))

整合工具类

package xml;

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

public class JAXBUtils {

    public static <T> T xmlStrToBean(String xmlStr,Class<T> clsLoader) throws JAXBException {

        JAXBContext context=null;
        StringReader reader=null;
        T res = null;
        try {
            //1、创建context
            context=JAXBContext.newInstance(clsLoader);
            //2、创建Unmarshaller
            Unmarshaller unmarshaller = context.createUnmarshaller();
            //3、实例化reader,将xml字符串放入参数
            reader=new StringReader(xmlStr);
            //4、使用unmarshaller.unmarshal 参数放入read
            res = (T) unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        System.out.println(res);
        //5、输出结果
        return res;

    }

    public static <T> String beanToXml(T t,String encoding) throws JAXBException {
        JAXBContext context=null;
        StringWriter writer=null;

        //1、创建上下文
        context = JAXBContext.newInstance(t.getClass());
        //2、创建Marshaller 这个是用于转换成xml的
        Marshaller marshaller = context.createMarshaller();
        //3、设置marshaller的属性
        //JAXB_FORMATTED_OUTPUT:格式化
        //JAXB_ENCODING:编码格式
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING,encoding);
        //4、实例化StringWriter
        writer=new StringWriter();
        //5、将实体类读取到writer中
        marshaller.marshal(t,writer);
        System.out.println(writer.toString());
        //6、输出结果
        return writer.toString();
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值