0%

xml和bean互转

说明

本文通过 JDK 中原生的 JAXB 实现 XMLjava bean 之间的互转,不依赖任何第三方包.

  • JAXBContext 类,是应用的入口,用于管理XML/Java绑定信息
  • Marshaller 接口,将Java对象序列化为XML数据
  • Unmarshaller 接口,将XML数据反序列化为Java对象

常用Annotation

  1. @XmlAccessorType(XmlAccessType.NONE) ,控制字段或属性的序列化
  • FIELD: JAXB 绑定类中的每个非静态、非瞬态字段将会自动绑定到 XML,除非由 XmlTransient 注释。
  • NONE: 所有字段或属性都不能绑定到 XML,除非使用一些 JAXB 注释专门对它们进行注释。
  • PROPERTY: JAXB 绑定类中的每个获取方法/设置方法对将会自动绑定到 XML,除非由 XmlTransient 注释。
  • PUBLIC_MEMBER:每个公共获取方法/设置方法对和每个公共字段将会自动绑定到 XML,除非由 XmlTransient 注释。
  1. @XmlRootElement
    xml 文件的根元素

  2. @XmlElement
    代表的生成xml的属性名称,一般用在属性上,或者set方法上。

  • 用法 @XmlElement(name="elementName")
  1. @XmlTransient
    放在属性上,或者set方法上,代表不进行序列化

  2. @XmlAttribute
    该属性作为xml的attribute

  • @XmlAttribute(name = "NAME")
  1. @XmlAccessorOrder
    控制JAXB 绑定类中属性和字段的排序

  2. @XmlJavaTypeAdapter
    使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML

  3. @XmlElementWrapper
    对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)

XML和Bean互转Util

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;

/**
 * @ClassName: FormatUtil
 * @Description: XML 和 JSON 互转工具
 * @Author: wuzhiyong
 * @Time: 2023/4/4 14:39
 * @Version: v1.0
 **/
public class FormatUtil {

    public static <T> T xmlToBean(String xml, Class<T> tClass) {
        Object object = null;
        try {
            JAXBContext context = JAXBContext.newInstance(tClass);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            object = unmarshaller.unmarshal(new StringReader(xml));
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return (T) object;
    }

    /**
     * 对象转xml
     *
     * @param obj
     * @return
     */
    public static String beanToXml(Object obj) {
        StringWriter writer = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            // 格式化
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            // 去掉生成xml的默认报文头 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
            writer = new StringWriter();
            marshaller.marshal(obj, writer);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return writer != null ? writer.toString() : null;
    }
}

测试

  • School.java
@Data
@NoArgsConstructor
@XmlRootElement(name = "SCHOOL")
@XmlAccessorType(XmlAccessType.NONE)
public class School {
    @XmlElement(name = "ADDRESS")
    private String addr;

    @XmlElement(name = "NUMBER")
    private int count;

    @XmlElement(name = "TEACHERS")
    private Teachers teachers;
}
  • Teachers.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Teachers {
    @XmlElement(name = "TEACHER")
    private List<Teacher> teachers;
}
  • Teacher.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Teacher {
    @XmlAttribute(name = "NAME")
    private String name;

    @XmlValue
    private String desc;
}
  • 测试.java
public class Test {
    public static void main(String[] args) {
        // 测试数据
        School school = new School();
        school.setAddr("Nanjing");
        school.setCount(1000);
        List<Teacher> teachers = new ArrayList<>();
        teachers.add(new Teacher("张三", "高级教师"));
        teachers.add(new Teacher("李四", "中级教师"));
        teachers.add(new Teacher("王五", "初级教师"));
        school.setTeachers(new Teachers(teachers));

        System.out.println(beanToXml(school));
        /**
         * 输出
         * <SCHOOL>
         *     <ADDRESS>Nanjing</ADDRESS>
         *     <NUMBER>1000</NUMBER>
         *     <TEACHERS>
         *         <TEACHER NAME="张三">高级教师</TEACHER>
         *         <TEACHER NAME="李四">中级教师</TEACHER>
         *         <TEACHER NAME="王五">初级教师</TEACHER>
         *     </TEACHERS>
         * </SCHOOL>
         */

        String xml = "<SCHOOL>\n" +
                "    <ADDRESS>Nanjing</ADDRESS>\n" +
                "    <NUMBER>1000</NUMBER>\n" +
                "    <TEACHERS>\n" +
                "        <TEACHER NAME=\"张三\">高级教师</TEACHER>\n" +
                "        <TEACHER NAME=\"李四\">中级教师</TEACHER>\n" +
                "        <TEACHER NAME=\"王五\">初级教师</TEACHER>\n" +
                "    </TEACHERS>\n" +
                "</SCHOOL>";
        School school1 = xmlToBean(xml, School.class);
        System.out.println(school.getAddr());
        System.out.println(school.getCount());
        System.out.println(school.getTeachers());
        /**
         * 输出
         * Nanjing
         * 1000
         * Teachers(teachers=[Teacher(name=张三, desc=高级教师), Teacher(name=李四, desc=中级教师), Teacher(name=王五, desc=初级教师)])
         */
    }
}