JAXB JavaBean与Xml之间转换问题之二
接着上一篇来说,上一篇主要讲述的是关于jaxb将实体转换为xml的使用方法和注解的一些过程,但是凡事都会有缺点,而上述方法的缺点就是marshaller解析的时候或自动过滤掉空字段,也就是不会解析全部的实体成员,如果是对于通过xml解析生成实体中对应的字段而言,是一个致命的缺点。因此有了今天的方法:
今天的东西并不多 但是需要大家了解java反射机制。。。。
代码块
代码块语法遵循标准markdown代码,例如:
package com.gsww.jup.util;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
/**
* @description <p>
* XML和java互转
* </p>
*/
public class XmlJavaUtils {
private XmlJavaUtils() {}
/**
* xmlTOjava xml转换java方法
*
* @description TODO
* @param class1
* @param xml
* @return
* @throws Exception
* @return Object
* @throws
*/
public static Object xmlToJava(Class<?> class1, String xml)
throws Exception {
// xml = xml.replaceAll("<", "<");
// xml = xml.replaceAll(">", ">");
JAXBContext jc = JAXBContext.newInstance(class1);
Unmarshaller unmar = jc.createUnmarshaller();
return unmar.unmarshal(new StringReader(xml));
}
/**
* java对象转成XML (没有<?xml version="1.0" encoding="gb2312" standalone="yes"?>)
* @param class1
* @param obj
* @return
* @throws Exception
*/
public static String javaToXml(Class<?> class1, Object obj)
throws Exception {
JAXBContext jc = JAXBContext.newInstance(class1);
Marshaller marshaller = jc.createMarshaller();
// 编码格式
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");//
// 是否格式化生成的xml串
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);//
// 是否省略xml头信息(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);//
StringWriter sw = new StringWriter();
String xml = "";
marshaller.marshal(obj, sw);
xml = sw.toString();
return xml;
}
/**
* java对象转成XML 有(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)
* @param class1
* @param obj
* @return
* @throws Exception
*/
public static String javaToXmls(Class<?> class1, Object obj)
throws Exception {
JAXBContext jc = JAXBContext.newInstance(class1);
Marshaller marshaller = jc.createMarshaller();
// 编码格式
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");//
// 是否格式化生成的xml串
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);//
// 是否省略xml头信息(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);//
//添加监听开始
marshaller.setListener(new XmlJavaUtils().new MarshallerListener());
new XmlJavaUtils().new MarshallerListener().afterMarshal(obj);
//添加监听结束
StringWriter sw = new StringWriter();
String xml = "";
marshaller.marshal(obj, sw);
xml = sw.toString();
return xml;
}
//新增该内部类,用来过滤空字段并赋值为“”
class MarshallerListener extends Marshaller.Listener {
//声明静态变量
public static final String BLANK_CHAR = "";
@Override
public void beforeMarshal(Object source) {
super.beforeMarshal(source);
//获取对象中的所有私有变量
Field[] fields = source.getClass().getDeclaredFields();
for (Field f : fields) {
//设置私有遍历可操作
f.setAccessible(true);
//获取字段上注解<pre name="code" class="java">
try {
if (f.getType() == String.class && f.get(source) == null) {
f.set(source, BLANK_CHAR);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
在上次方法的基础上 ,添加改内部类和方法中的两句监听代码就大功告成,亲测有用。
效果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<GasiListImpQtCharge>
<adminisrativeDivisionCode>32342432</adminisrativeDivisionCode>
<amount>金额-1</amount>
<chargeBasis>收费标准-1</chargeBasis>
<chargeItemName></chargeItemName>
<createName>孔繁洁</createName>
<createTime>2017-12-07 17:21:28</createTime>
<createUser>8a929b835fe291d4015fe2afe18b0002</createUser>
<itemGuid>4028b18160302d68016030479f350012</itemGuid>
<operSync></operSync>
<pkId>4028b18160302d68016030479f380014</pkId>
<reductionDesc>减免说明-1</reductionDesc>
<state>1</state>
<syncSign>0</syncSign>
<updateName></updateName>
<updateTime></updateTime>
<updateUser></updateUser>
</GasiListImpQtCharge>
</root>