JAXB 使用记录

参考资料

什么是 JAXB ?

开源中国:

JAXB(Java Architecture for XML Binding简称JAXB)允许Java开发人员将Java类映射为XML表示方式。JAXB提供两种主要特性:将一个Java对象序列化为XML,以及反向操作,将XML解析成Java对象。换句话说,JAXB允许以XML格式存储和读取数据,而不需要程序的类结构实现特定的读取XML和保存XML的代码。

package org.black.demo.xstream;

import java.io.Serializable;
import java.util.Arrays;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * 用户
 */
@XmlRootElement
//@XmlElement
public class User implements Serializable
{
    // serialVersionUID IDE自动生成的序列化ID
    private static final long serialVersionUID = -3552351542858137630L;
    // 姓名
    private String name;
    // 性别
    private String sex;
    // 年龄
    private Integer age;
    // 身高
    private Double height;
    // 分数
    private Double[] points;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Double getHeight() {
        return height;
    }
    public void setHeight(Double height) {
        this.height = height;
    }

    public Double[] getPoints() {
        return points;
    }
    public void setPoints(Double[] points) {
        this.points = points;
    }
    @Override
    public String toString() {
        return "User [name=" + name + ", sex=" + sex + ", age=" + age + ", height=" + height + ", points=" + Arrays.toString(points) +"]";
    }
}

package org.black.demo.jaxb;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.black.demo.xstream.User;

import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class JavaArcXMlBean {

    public static void main(String[] args) {

        try {
            // contextPath 是Java对象的包名集合,test.jaxb就是包名
            JAXBContext jc = JAXBContext.newInstance(User.class);
            // marshalling 是计算机科学中把一个对象的内存表示变换为适合存储或发送的数据格式的过程
            // marshaller 是控制 marshalling 处理
            Marshaller marshaller = jc.createMarshaller();
            User admin = new User();
            admin.setName("管理员111");
            admin.setAge(27);
            admin.setHeight(180.00);
            admin.setSex("男");
            Double[] points = new Double[2];
            points[0] = 182.00;
            points[1] = 100.00;

            admin.setPoints(points);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
            // 将Java对象序列化为xml 文件
            ByteOutputStream bo = new ByteOutputStream();
            marshaller.marshal(admin, bo);
            bo.flush();
            bo.close();
            ByteInputStream bi =  bo.newInputStream();
            System.out.println("序列化后:" + new  String (bi.getBytes()));
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            // 真正反序列化 xml 文件,得到
            User adminCpoy = (User) unmarshaller.unmarshal(bi);
            bi.close();
            System.out.println("adminCpoy:" + adminCpoy);

        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

&#x5E8F;&#x5217;&#x5316;&#x540E;&#xFF1A;<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <age>27</age>
    <height>180.0</height>
    <name>&#x7BA1;&#x7406;&#x5458;111</name>
    <points>182.0</points>
    <points>100.0</points>
    <sex>&#x7537;</sex>
</user>

adminCpoy:User [name=&#x7BA1;&#x7406;&#x5458;111, sex=&#x7537;, age=27, height=180.0, points=[182.0, 100.0]]

单独写一个 JAXBUtil.Java工具类 提供序列化和反序列化方法.

package org.black.demo.jaxb;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

/**
 * JAXB 序列化工具类
 * @author black
 * @date 2021-12-10 18:44:038
 */
public class JAXBUtil {

    /**
     * 序列化为xml字符串
     * @param obj
     * @return
     * @throws JAXBException
     * @throws IOException
     */

    public static String serialize(Object obj) throws JAXBException, IOException {
        // contextPath 是Java对象的包名集合,test.jaxb就是包名
        JAXBContext jc;
        StringBuilder builder = new StringBuilder();
        try (ByteOutputStream bo = new ByteOutputStream();) {
            jc = JAXBContext.newInstance(obj.getClass());
            // marshalling 是计算机科学中把一个对象的内存表示变换为适合存储或发送的数据格式的过程
            // marshaller 是控制 marshalling 处理
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
            // 将Java对象序列化为xml 字符串
            marshaller.marshal(obj, bo);
            bo.flush();
            return new String(bo.getBytes(),"utf8");
        }
    }

    /**
     * xml字符串反序列化为对象
     * @param
     * @param in
     * @param t
     * @throws JAXBException
     * @throws ParserConfigurationException
     * @throws SAXException
     */
    public static  T deserialize(String xml, T t) throws JAXBException, SAXException, ParserConfigurationException {
        JAXBContext jc = JAXBContext.newInstance(t.getClass());
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Source source =  trunSource(xml);
        JAXBElement et = unmarshaller.unmarshal(source,t.getClass());
         return (T)et.getValue();
    }

    private static Source trunSource(String xmlStr) throws SAXException, ParserConfigurationException{
         StringReader reader = new StringReader(xmlStr);
         SAXParserFactory sax = SAXParserFactory.newInstance();
        sax.setNamespaceAware(false);
        XMLReader xmlReader = sax.newSAXParser().getXMLReader();
        Source source = new SAXSource(xmlReader, new InputSource(reader));
         return source;
    }
}

xml 节点结构:

<root>
    +
    + ---- <header>
    +
    + ---- <object>
    + ---- <object>
    ...

</object></object></header></root>
package org.black.demo.jaxb;

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "root")
public class XMLFileRoot {

    // root 标签属性 id
    @XmlAttribute
    private String id;

    // root 标签属性 type
    @XmlAttribute
    private String type;

    // root 标签子标签 header
    @XmlElement(name = "header")
    private XMLHeader header;

    // XmlElementRef 根据 ContentObject 类型来映射xml 标签
    @XmlElementRef
    private List objects;

    // 无参构造器必须存在,否则报"does not have a no-arg default constructor"
    public XMLFileRoot() {
    }

    public XMLFileRoot(String id, String type) {
        super();
        this.id = id;
        this.type = type;
    }

    public void setHeader(XMLHeader header) {
        this.header = header;
    }

    public void setObjects(List objects) {
        this.objects = objects;
    }
}

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "header")
public class XMLHeader {

    // header 标签属性 name
    @XmlAttribute
    private String name;

    // header 标签属性 desc
    @XmlAttribute
    private String desc;

    // header 标签的值,示例: "
    @XmlValue
    private String metadate ="";

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

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

object 存在公用属性 id 和 desc,这里我提取了一个父类 ContentObject,并用 @XmlSeeAlso 指定 子类使用ContentObject的属性:

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;

// @XmlSeeAlso 指示 JAXB 绑定这个类时,也绑定其他类
@XmlSeeAlso(value = {Book.class, Phone.class})
public class ContentObject {
    @XmlAttribute
    protected String id;

    @XmlAttribute
    protected String name;

}

两个子类 Book 和Phone:

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="object")
public class Book extends ContentObject{

    // 价格
    @XmlAttribute
    private Double price;

    // 无参构造器必须存在,否则报"does not have a no-arg default constructor"
    public Book() {

    }

     public Book(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

package org.black.demo.jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "object")
public class Phone extends ContentObject {

    // 生产日期
    @XmlAttribute
    private String createDate;

    // 无参构造器必须存在,否则报"does not have a no-arg default constructor"
    public Phone() {

    }

    public Phone(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }
}
package org.black.demo.jaxb;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBException;

public class JaxbUtilTest {

    public static void main(String[] args) {
        // root
        XMLFileRoot root = new XMLFileRoot("1", "root");

        // header
        XMLHeader header = new XMLHeader();
        header.setName("xml head");
        header.setDesc("这是Jaxb 生成的xml格式数据");

        root.setHeader(header);

        // object
        List objects = new ArrayList();
        Book book = new Book("1", "诛仙");
        // 价格
        book.setPrice(88.00);
        Phone phone = new Phone("2", "苹果手机");
        // 生产日期
        phone.setCreateDate("2022-01-01 00:00:00");
        objects.add(book);
        objects.add(phone);

        root.setObjects(objects);

        // 生成xml
        String xml;
        try {
            xml = JAXBUtil.serialize(root);
            System.out.println("生成的XML :");
            System.out.println(xml);
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试结果:

&#x751F;&#x6210;&#x7684;XML :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root id="1" type="root">
    <header name="xml head" desc="&#x8FD9;&#x662F;Jaxb &#x751F;&#x6210;&#x7684;xml&#x683C;&#x5F0F;&#x6570;&#x636E;"><![CDATA[+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs]]></header>
    <object price="88.0" id="1" name="&#x8BDB;&#x4ED9;">
    <object createdate="2022-01-01 00:00:00" id="2" name="&#x82F9;&#x679C;&#x624B;&#x673A;">
</object></object></root>

Original: https://www.cnblogs.com/lihw-study/p/15673260.html
Author: 不安分的黑娃
Title: JAXB 使用记录

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/593475/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球