看到别人有个1024的勋章,特意留了一篇在今年的10.24日,看看会不会获得。
在日常开发中可能涉及接口之间的相互调用,虽然在现在微服务的理念推广下,很多公司都采用轻量级的JSON格式做为序列化的格式,但是不乏有些公司还是有一些XML格式的报文,最近就在对接某个合作方的时候遇到了XML报文。在JSON报文爽快的转换下很难试用一个一个的拿报文参数,还是希望能直接将报文转换成Bean。接下来就了解到了一些插件,因为代码中使用了泛型,所以经过多方对比之后还是选择了JAXB,接下来就介绍一下JAXB的使用。
1.创建两个Bean来作为转换模版(使用泛型),@XmlRootElement(name = "GIRL") 用来对应报文的封装节点;@XmlAccessorType(XmlAccessType.FIELD) 表示只将变量转换为实体,配合 @Data 使用爽得很。
package com.example.dragon.main.dao.model.xmlutil;
import lombok.Data;
import javax.xml.bind.annotation.*;
import java.util.List;
/**
* @ClassNAME girl
* @Description 女孩儿对象
* @Author XiongMao
* @Date 2019-9-8
*/
@Data
@XmlRootElement(name = "GIRL")
@XmlAccessorType(XmlAccessType.FIELD)
public class Girl<T> {
@XmlElement(name = "NAME")
private String name;
/**
* XmlAnyElement 这个注解可以去调生成的xml中带的xsi:type等信息,使用这个注解就不能使用 @XmlElement,
* 需要在泛型对应的实体上增加 @XmlRootElement 注解
* XmlElementWrapper 这个注解可以在集合外层包装一个节点
*/
@XmlAnyElement(lax = true)
private T ageAndSex;
}
package com.example.dragon.main.dao.model.xmlutil;
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;
/**
* @ClassNAME AgeAndSex
* @Description 年龄与性别对象
* @Author XiongMao
* @Date 2019-9-8
*/
@Data
@XmlRootElement(name="AGEANDSEX")
@XmlAccessorType(XmlAccessType.FIELD)
public class AgeAndSex {
@XmlElement(name="AGE")
private String age;
@XmlElement(name="SEX")
private String sex;
}
2.做一个工具类封装转换的代码,代码中都有注释,其中借鉴了一些博客内容,时间久了忘记了,如有发现请告知:
package com.example.dragon.main.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 XmlUtil
* @Description XML与bean互相转换
* @Author XiongMao
* @Date 2019-9-7
*/
public class XmlUtil {
/**
* @Description bean转成xml
* @Param [t]
* @Return java.lang.String
*/
public static <T> String beanToXml(T t) throws JAXBException {
//获得 JAXBContext 类的新实例。参数为类的地址
JAXBContext context = JAXBContext.newInstance(t.getClass());
//创建一个可以用来将 java 内容树转换为 XML 数据的 Marshaller 对象。
Marshaller m = context.createMarshaller();
//创建一个StringWriter流将接收到的对象流写入xml字符串
StringWriter sw = new StringWriter();
//调用marshal方法进行转换
m.marshal(t,sw);
//将读取到的StringWriter流转成String返回
return sw.toString();
}
/**
* @Description bean转成xml(泛型使用)
* @Param [t]
* @Return java.lang.String
*/
public static <T> String beanToXml(T t, Class c) throws JAXBException {
//获得 JAXBContext 类的新实例。参数为类的地址
JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
//创建一个可以用来将 java 内容树转换为 XML 数据的 Marshaller 对象。
Marshaller m = context.createMarshaller();
//创建一个StringWriter流将接收到的对象流写入xml字符串
StringWriter sw = new StringWriter();
//调用marshal方法进行转换
m.marshal(t,sw);
//将读取到的StringWriter流转成String返回
return sw.toString();
}
/**
* @Description xml 转成 bean
* @Param [xml, t]
* @Return T
*/
public static <T> T xmlToBean(String xml, T t) throws JAXBException {
获得 JAXBContext 类的新实例。参数为类的地址
JAXBContext context = JAXBContext.newInstance(t.getClass());
//创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。
Unmarshaller um = context.createUnmarshaller();
//创建一个StringReader将xml报文转成流
StringReader sr = new StringReader(xml);
//调用unmarshal进行转换,并把Object类型强转为调用者的类型
t = (T) um.unmarshal(sr);
//将对象返回给调用者
return t;
}
/**
* @Description xml 转成 bean(泛型使用)
* @Param [xml, t]
* @Return T
*/
public static <T> T xmlToBean(String xml, T t, Class c) throws JAXBException {
获得 JAXBContext 类的新实例。参数为类的地址
JAXBContext context = JAXBContext.newInstance(t.getClass(),c);
//创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。
Unmarshaller um = context.createUnmarshaller();
//创建一个StringReader将xml报文转成流
StringReader sr = new StringReader(xml);
//调用unmarshal进行转换,并把Object类型强转为调用者的类型
t = (T) um.unmarshal(sr);
//将对象返回给调用者
return t;
}
}
3.接下来做一个main方法测试一下运行结果:
main方法:
Girl girl = new Girl();
girl.setName("小红");
AgeAndSex ageAndSex = new AgeAndSex();
ageAndSex.setAge("18");
ageAndSex.setSex("女");
girl.setAgeAndSex(ageAndSex);
System.out.println("组装完成的对象值为:" + girl);
//方法调用并输出
Girl newGirl = new Girl();
String xml;
try {
xml = XmlUtil.beanToXml(girl, AgeAndSex.class);
System.out.println("bean转成xml格式为:" + xml);
newGirl = XmlUtil.xmlToBean(xml, newGirl, AgeAndSex.class);
System.out.println("xml转成bean格式为:" + newGirl);
} catch (JAXBException e) {
e.printStackTrace();
}
结果:
组装完成的对象值为:Girl(name=小红, ageAndSex=AgeAndSex(age=18, sex=女))
bean转成xml格式为:<?xml version="1.0" encoding="UTF-8" standalone="yes"?><GIRL><NAME>小 红</NAME><AGEANDSEX><AGE>18</AGE><SEX>女</SEX></AGEANDSEX></GIRL>
xml转成bean格式为:Girl(name=小红, ageAndSex=AgeAndSex(age=18, sex=女))
使用起来其实挺简单的,因为时间有限没有去研究他的原理,如有知道的可以补充。还是建议大家多去了解技术的原理,因为如今技术实现越来越简单,但是大家也离原理越来越远。