对象和xml之间的转化
在项目开发中有时候与其他第三方接口对接需要用到,参数和响应有时候会以xml的形式传递
需要导入的依赖是 pom
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
相关工具类的
XStreamFactory
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NameCoder;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDomDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import java.io.Writer;
import java.lang.reflect.Field;
public class XStreamFactory {
public static final String CDATA_PREFIX = "<![CDATA[";
public static final String CDATA_SUFFIX = "]]>";
public static XStream getXStream() {
final NameCoder nameCoder = new NoNameCoder();
XStream xStream = new XStream(new XppDomDriver(nameCoder) {
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out, nameCoder) {
boolean cdataFlag = false;
Class<?> targetClass = null;
@Override
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
if (targetClass == null) {
targetClass = clazz;
}
cdataFlag = isCDATA(targetClass, name);
}
@Override
public void writeText(QuickWriter writer, String text) {
if (cdataFlag) {
writer.write(CDATA_PREFIX);
writer.write(text);
writer.write(CDATA_SUFFIX);
} else {
writer.write(text);
}
}
};
}
});
// 设置默认的安全校验
XStream.setupDefaultSecurity(xStream);
// 使用本地的类加载器
xStream.setClassLoader(XmlUtils.class.getClassLoader());
// 允许所有的类进行转换
xStream.addPermission(AnyTypePermission.ANY);
return xStream;
}
private static boolean isCDATA(Class<?> clazz, String fieldAlias) {
//检查类本身
boolean cdataFlag = isExistCDATA(clazz, fieldAlias);
if (cdataFlag) {
return cdataFlag;
}
//继续检查父类
Class<?> superClazz = clazz.getSuperclass();
while (!superClazz.equals(Object.class)) {
cdataFlag = isExistCDATA(superClazz, fieldAlias);
if (cdataFlag) {
return cdataFlag;
}
superClazz = superClazz.getClass().getSuperclass();
}
return false;
}
/**
* 检查是否有 @XStreamCDATA 注解
* @param clazz clazz
* @param fieldAlias fieldAlias
* @return
*/
private static boolean isExistCDATA(Class<?> clazz, String fieldAlias) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getAnnotation(XStreamCDATA.class) != null) {
XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class);
if (xStreamAlias != null && fieldAlias.equals(xStreamAlias.value())) {
return true;
} else {
if (fieldAlias.equals(field.getName())) {
return true;
}
}
}
}
return false;
}
}
XStreamCDATA 这个注解是为了处理xml的内容需要添加<![CDATA[]>
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XStreamCDATA {
}
XmlUtils
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.security.AnyTypePermission;
import org.apache.commons.lang3.StringUtils;
public class XmlUtils {
private static String XML_TAG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
private static final String OBJ = "obj";
private static final XStream xStream = XStreamFactory.getXStream();
/**
* 对象转xml
*
* @param obj 对象
* @return
*/
public static String toXml(Object obj) {
xStream.processAnnotations(obj.getClass());
//如果生成的是Objec不显示class属性
xStream.aliasSystemAttribute(null, "class");
return XML_TAG + xStream.toXML(obj);
}
/**
* 定制化需求 特殊处理XStream对象
* @return
*/
private static XStream getInstance() {
XStream xStream = new XStream(new DomDriver("UTF-8")) {
/**
* 忽略xml中多余字段
*/
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new MapperWrapper(next) {
@SuppressWarnings("rawtypes")
@Override
public boolean shouldSerializeMember(Class definedIn, String fieldName) {
if (definedIn == Object.class) {
return false;
}
return super.shouldSerializeMember(definedIn, fieldName);
}
};
}
};
// 设置默认的安全校验
XStream.setupDefaultSecurity(xStream);
// 使用本地的类加载器
xStream.setClassLoader(XmlUtils.class.getClassLoader());
// 允许所有的类进行转换
xStream.addPermission(AnyTypePermission.ANY);
return xStream;
}
/**
* xml 转 bean
*
* @param xml
* @param clazz
* @param <T>
* @return
*/
public static <T> T xmlToBean(String xml, Class<T> clazz) {
XStream instance = getInstance();
instance.processAnnotations(clazz);
instance.autodetectAnnotations(true);
T obj = (T) instance.fromXML(xml);
return obj;
}
}
测试对象
TestDemo
import com.gyjx.outgateway.modle.request.UserNumber;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("root")
public class TestDemo {
@XStreamAlias("UserNumber")
private String userNumber;
@XStreamAlias("name")
// @XStreamCDATA
private String name;
@XStreamAlias("Record")
private UserNumber record;
public TestDemo() {
}
public String getUserNumber() {
return userNumber;
}
public void setUserNumber(String userNumber) {
this.userNumber = userNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UserNumber getRecord() {
return record;
}
public void setRecord(UserNumber record) {
this.record = record;
}
@Override
public String toString() {
return "TestDemo{" +
"userNumber='" + userNumber + '\'' +
", name='" + name + '\'' +
", record=" + record +
'}';
}
}
UserNumber
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("Record")
public class UserNumber {
@XStreamAlias("UserNumber")
private String userNumber;
public UserNumber() {
}
public String getUserNumber() {
return userNumber;
}
public void setUserNumber(String userNumber) {
this.userNumber = userNumber;
}
@Override
public String toString() {
return "UserNumber{" +
"userNumber='" + userNumber + '\'' +
'}';
}
}
对象与xml相互转化
@Test
public void testXml(){
TestDemo testDemo = new TestDemo();
testDemo.setName("qiuwei");
testDemo.setUserNumber("13298878771");
UserNumber userNumber = new UserNumber();
userNumber.setUserNumber("17611013092");
testDemo.setRecord(userNumber);
//对象-->xml
String s = XmlUtils.toXml(testDemo);
System.out.println(s);
System.out.println("===============================");
//xml-->对象
TestDemo testDemo1 = XmlUtils.xmlToBean(s, TestDemo.class);
System.out.println(testDemo1.toString());
}
测试结果
如何优雅处理<![CDATA[]>
在需要转化的属性上添加 @XStreamCDATA 注解
测试结果
当然 处理<![CDATA[]> 还有其他方式这里的工具类已经集成的处理方式,大家可以根据自己的项目需求进行集成