一、问题
在传输XML请求报文的时候,遇到一个问题,就是xml内容里强制将我的双引号转换为
&qut;
但是,我不希望他转换;就像保留原汁原味的双引号;如何处理?
二、解决
参考了【XStream添加 CDATA标签解析】博客的处理办法,并且做了修改,如果有本文不一样的场景,可以参考原文;
思路是:在需要保护的内容外添加
<![CDATA[内容]]>
标签;具体的思路是:
1.新增一个标记需要添加<!CDATA[]]标签的注解,凡是实体类中的字段上打了该标签的,自动为其包裹;
2.处理带标签的字段;
三、解决
3.1、新增标签;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Auther
* @title: XStreamCDATA
* @projectName generatorSqlmapCustom
* @description: TODO
* @date 23/05/201919:39
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XStreamCDATA {
}
3.2、新增处理工厂
将需要添加标签的实体,传入该工厂,出来的参数,就是带了
<![CDATA[]]>
标签的实体;
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.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDomDriver;
import java.io.Writer;
import java.lang.reflect.Field;
/**
* @author Auther
* @title: XStreamFactory
* @projectName generatorSqlmapCustom
* @description: TODO
* @date 23/05/201919:40
*/
public class XStreamFactory {
public static final String CDATA_PREFIX = "<![CDATA[";
public static final String CDATA_SUFFIX = "]]>";
public static XStream getXStream(final XmlFriendlyNameCoder nameCoder) {
//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);
}
}
};
}
});
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;
}
}
3.3、使用
在xml处理处:
XStream xStream = XStreamFactory.getXStream(new XmlFriendlyNameCoder("_-","_"));
这样,带XStreamCDATA注解的实体类字段,就会在其内容外,就会被
<![CDATA[]]>
包裹;