JavaBean与Xml之间转换工具类
-
前言
最近有个需求,需要和外围系统做webService接口,因此需要将报文组装好进行接口调用,即将javabean转为xml内容,使用javax包中的JAXBContext进行了定制化修改(主要是去除了标签头的一部分不需要的属性,比如命名空间等待信息),形成的工具类。
注意在使用List内嵌对象列表的时候,内部对象的标签头由外部标签的对象名称决定,参考下面实例的外层对象的ITEM属性
关于Xml相关的注解,这里不进行解释,请查阅其他相关资料
-
工具类源码
package com.webservice.util;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.List;
@Slf4j
public class JaxbUtil {
/**
* JavaBean转换成xml
* 默认编码UTF-8
* @param obj
* @return
*/
public static String convertToXml(Object obj) {
return convertToXml(obj, "UTF-8");
}
/**
* JavaBean转换成xml
* 默认格式化
* @param obj
* @param encoding
* @return
*/
public static String convertToXml(Object obj, String encoding) {
return convertToXml(obj,encoding,true,true);
}
/**
* JavaBean转换成xml
* @param obj
* @param encoding
* @param isFormat 是否格式化
* @return
*/
public static String convertToXml(Object obj, String encoding, boolean isFormat,boolean isMove) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, isFormat);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = isMove?remove(writer.toString(),encoding):writer.toString();
} catch (Exception e) {
log.error("convertToXml error:",e);
}
return result;
}
/**
* xml转换成JavaBean
* @param xml
* @param c
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T converToJavaBean(String xml, Class<T> c) {
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
} catch (Exception e) {
log.error("converToJavaBean error:",e);
}
return t;
}
/**
* 默认移除属性,命名空间
* @param xml
* @return
* @throws Exception
*/
public static String remove(String xml,String encoding)throws Exception{
SAXReader reader = new SAXReader();
Document doc = reader.read(new StringReader(xml));
Element element = doc.getRootElement();
removeAttr(element);
return asXml(element,encoding);
}
/**
* 移除xs xsi命名空间 以及 type 属性
* @param ele
*/
private static void removeAttr(Element ele){
try{
if(ele.elements().size() == 0){
ele.remove(ele.getNamespaceForPrefix("xs"));
ele.remove(ele.getNamespaceForPrefix("xsi"));
Attribute attr = ele.attribute("type");
if(attr!=null)ele.remove(attr);
}else{
List<Element> elements = ele.elements();
for(Element e:elements){
removeAttr(e);
}
}
}catch (Exception e){
log.error("parse error:",e);
}
}
/**
* 避免标签闭合
* @param body
* @return
*/
private static String asXml(Element body,String encoding) {
OutputFormat format = new OutputFormat();
format.setEncoding(encoding);
format.setExpandEmptyElements(true);
StringWriter out = new StringWriter();
XMLWriter writer = new XMLWriter(out, format);
try {
writer.write(body);
writer.flush();
} catch (IOException e) {
log.error("read file error:",e);
}
String xml = "<?xml version=\"1.0\" encoding=\""+encoding+"\" ?>\n";
return xml + out.toString();
}
}
-
报文样例
<?xml version="1.0" encoding="UTF-8" ?>
<DATA>
<SEND_DATE>2021-10-08 11:31:00</SEND_DATE>
<ITEMS>
<ITEM>
<OBJ_ID>5C0FF2D2-05CA-4A74-BDDA-38CE1DB3E200-03952</OBJ_ID>
<TZDBH>第JSY-NaRi-20210618-1号</TZDBH>
<OPER_TYPE>调整情况</OPER_TYPE>
<ORDER_PERSON>张才斌</ORDER_PERSON>
<ZXSJ>2021-09-15 11:30:00</ZXSJ>
<EXE_PERSON>冯旭阳</EXE_PERSON>
<EXE_STATUS>已执行</EXE_STATUS>
</ITEM>
<ITEM>
<OBJ_ID>5C0FF2D2-05CA-4A74-BDDA-38CE1DB3E200-03952</OBJ_ID>
<TZDBH>第JSY-NaRi-20210618-1号</TZDBH>
<OPER_TYPE>调整情况</OPER_TYPE>
<ORDER_PERSON>张才斌</ORDER_PERSON>
<ZXSJ>2021-09-15 11:30:00</ZXSJ>
<EXE_PERSON>冯旭阳</EXE_PERSON>
<EXE_STATUS>已执行</EXE_STATUS>
</ITEM>
</ITEMS>
</DATA>
-
外层数据JavaBean
package com.webservice.czpservice.entity.oms.databean;
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@Data
@XmlRootElement(name = "DATA")
@XmlAccessorType(XmlAccessType.FIELD)
public class AkqtSginXmlBean {
@XmlElement(name = "SEND_DATE", required = true, nillable = true)
private String sendDate;
@XmlElementWrapper(name = "ITEMS", required = true)
private List<AkqtSginInfoXmlBean> ITEM;
}
-
内层数据JavaBean
package com.webservice.czpservice.entity.oms.databean;
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;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class AkqtSginInfoXmlBean {
@XmlElement(name = "OBJ_ID", required = true, nillable = true)
private String objId;
@XmlElement(name = "TZDBH", required = true, nillable = true)
private String tzdBh;
@XmlElement(name = "OPER_TYPE", required = true, nillable = true)
private String operType;
@XmlElement(name = "ORDER_PERSON", required = true, nillable = true)
private String orderPerson;
@XmlElement(name = "ZXSJ", required = true, nillable = true)
private String zxsj;
@XmlElement(name = "EXE_PERSON", required = true, nillable = true)
private String exePerson;
@XmlElement(name = "EXE_STATUS", required = true, nillable = true)
private String exeStatus;
}