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

通过JAXB将对象与XML相互转换

发布时间:2020-12-16 06:22:03 所属栏目:百科 来源:网络整理
导读:JAXB是一个非常通用的工业标准,它可以对一个实体类进行配置,指定该对象与XML或JSON格式数据的转换映射。本文将介绍如何不借助第三方工具,直接将Java Object与XML文档进行双向转换的操作。关于JSON格式的转换以及JAXB注解配置的使用,暂不做讨论,将后续再

  JAXB是一个非常通用的工业标准,它可以对一个实体类进行配置,指定该对象与XML或JSON格式数据的转换映射。本文将介绍如何不借助第三方工具,直接将Java Object与XML文档进行双向转换的操作。关于JSON格式的转换以及JAXB注解配置的使用,暂不做讨论,将后续再写文章进行整理。
  一些如Jackson等著名的第三方工具确实对JAXB提供了非常好的支持,但有的时候引入它们也是一种成本。实际上对于简单的使用场景,我们可以使用javax.xml.bind包中的工具完成转换操作。
  例如有一个Person类,其JAXB注解配置的代码如下:

package com.tech4j.demo;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {

    private String name;
    private Integer age;

    // 省略 Getter Setter

}

  非常简单,其中只有一个注解@XmlRootElement。但是需要特别注意,如果希望对类属性进行JAXB配置,最好将注解写在其对应的Getter方法上,而不要写在类属性上。否则后文使用的JAXBContext将会报出错误。下面给出一种正确的配置示例:

package com.tech4j.demo;

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

@XmlRootElement
public class Person {

    private String name;
    private Integer age;

    @XmlElement(name = "XingMing")
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

  下面这个工具类提供了fromXml()方法将XML字符串转换为对象,也提供了反向的toXml()方法将对象转换为XML字符串:

package com.tech4j.demo;

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

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

public class JaxbUtil {

    @SuppressWarnings("unchecked")
    public synchronized static <T> T fromXml(String xmlStr,Class<T> _class) {
        T result = null;
        try {
            StringReader reader = new StringReader(xmlStr);
            JAXBContext context = JAXBContext.newInstance(_class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            Object obj = unmarshaller.unmarshal(reader);
            if (!_class.isAssignableFrom(obj.getClass())) {
                throw new RuntimeException("转换得到的对象并非指定类型范围内的对象!");
            }
            result = (T) obj;
            reader.close();
        } catch (JAXBException | RuntimeException e) {
            e.printStackTrace();
        }
        return result;
    }

    public synchronized static String toXml(Object obj) {
        String xmlStr = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());

            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj,writer);
            xmlStr = writer.toString();
            writer.close();
        } catch (JAXBException | IOException e) {
            e.printStackTrace();
        }
        return xmlStr;
    }

}

  需要注意其中isAssignableFrom()方法的使用,它用来通过两个反射对象判断后者能否安全地转换为前者对应的类对象。
  如前所述,如果我们将@XmlElement(name = "XingMing")这个注解写在了Person的类属性name上,那么程序将会报出错误,说拥有两个同名的属性name。错误提示如下所示:

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
类的两个属性具有相同名称 "name"
    this problem is related to the following location:
        at public java.lang.String com.tech4j.demo.Person.getName()
        at com.tech4j.demo.Person
    this problem is related to the following location:
        at private java.lang.String com.tech4j.demo.Person.name
        at com.tech4j.demo.Person

(编辑:李大同)

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

    推荐文章
      热点阅读