Java对象与XML报文互转

XML由于可以跨开发语言进行交互,使其在越来越多的领域使用,典型的领域就有金融银行业。那么这么流行的交互报文格式,怎么让它转为我们的JAVA对象呢?需要我们一个NODE一个NODE的去解析吗?答案肯定是不需要的。以下提供通过转换工具类方法:

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class XmlUtil {

/**
* JAVA对象转xml
* @param object java对象
* @param <T>
* @return xml字符串
* @throws JAXBException
*/
public static <T> String convertXml(T object) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(object.getClass());
// 创建 Marshaller装配器实例
Marshaller marshaller = context.createMarshaller();
// 可以设置的属性参见方法:com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.setProperty()
marshaller.setProperty(Marshaller.JAXB_ENCODING, StandardCharsets.UTF_8.name());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
// 指定xml文件头
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 将xml写入流中
marshaller.marshal(object, outputStream);
// 将流转换成字符串
return new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
}

/**
* xml报文转java对象
* @param xml xml报文
* @param clazz java对象类
* @param <E>
* @return java对象
* @throws JAXBException
*/
public static <E> E convertObject(String xml, Class<E> clazz) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(clazz);
// 创建unmarshaller解组器实例
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader stringReader = new StringReader(xml);
return (E) unmarshaller.unmarshal(stringReader);
}

/**
* xml文件流转java对象
* @param inputStream xml文件流
* @param clazz java对象类型
* @param <E>
* @return java对象
* @throws JAXBException
*/
public static <E> E convertObject(InputStream inputStream, Class<E> clazz) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(clazz);
// 创建unmarshaller解组器实例
Unmarshaller unmarshaller = context.createUnmarshaller();
return (E) unmarshaller.unmarshal(inputStream);
}
}

常见注解如下:

注解@XmlRootElement(name="节点名"),该注解是Java对象生成xml必须的注解;

注解@XmlElementWrapper(name="节点名"),如果Java对象中有List,生成的xml可以被指定的name节点包裹;

注解@XmlType(name="",propOrder={}),如果需要指定节点顺序,使用propOrder属性;

注解@XmlType,用于指定字段的节点名称等属性;

注解@XmlTransient,用于标记某些字段不生成xml

更多了解JAXB:https://www.w3cschool.cn/jaxb2/jaxb2-5hnk2zo8.html

其实我们经常会遇到这种情况,需求过来,给过来的是xml样例,这时候就需要我们去构建与之对应的java bean,字段少的话还好,如果有很多,有什么办法可以自动生成吗?

我们能考虑到的,就是早已存在的技术,就是使用xjc命令。

xjc命令使用详情见:https://www.w3cschool.cn/jaxb2/jaxb2-6haf2zou.html

如何使用xml生成xsd,可以参考:https://github.com/wiztools/xsd-gen,也可以使用在线版的:https://www.freeformatter.com/xsd-generator.html

经过的我多次试验xml转xsd不是100%准确的,会有一些瑕疵,需要自己做细微调整。

posted @ 2023-04-13 17:51  今夕是何年?  阅读(1126)  评论(0编辑  收藏  举报