了解CDATA
在XML元素中,”<”和”&”是⾮法的,如果使⽤这些特殊字符,那么解析器在解析⽂档时会产⽣错误。为了避免此类错误,需要
<user>age < 25</user> //<user>age < 25</user>
在 XML 中有 5 个预定义的实体引⽤:
电石炉
实体引⽤符号说明
<<⼩于
>>⼤于
&&和号
'‘省略号
"“引号
注释:严格地讲,在 XML 中仅有字符 “<”和”&” 是⾮法的。省略号、引号和⼤于号是合法的,但是把它们替换为实体引⽤是个好的习惯。
⽽ CDATA 指的是不应由 XML 解析器进⾏解析的⽂本数据(Unparsed Character Data),CDATA 部分中的所有内容都会被解析器忽略,CDATA 部分由 <![CDATA[ 开始,由 ]]> 结束。所以,我们可以使⽤ CDATA 标签帮我们忽略某些特殊字符。
XStream是⼀个Java对象与XML互相转换的⼯具类库。
⾸先,先说说实现原理吧,由于对象不是所有字段都增加 CDATA 标签,我们可以使⽤⾃定义注解⽅式,在需要添加 CDATA 标签的字段加上注解,然后改写XPPDriver,通过反射查添加注解的field,在输出XML⽂本时加上<![CDATA[和]]>。废话不多说…… 实现
⼀、创建注解
创建⾃定义注解@XStreamCDATA:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XStreamCDATA {
}
⼆、创建XStreamFactory,改写XPPDriver
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;
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(Constants.CDATA_PREFIX);
writer.write(text);
writer.write(Constants.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 = Superclass();
while (!superClazz.equals(Object.class)) {
cdataFlag = isExistCDATA(superClazz, fieldAlias);
if (cdataFlag) {
return cdataFlag;
}
superClazz = Class().getSuperclass();
}
return false;
}
/**
* 检查是否有 @XStreamCDATA 注解
* @param clazz clazz
* @param fieldAlias fieldAlias
* @return
*/
private static boolean isExistCDATA(Class<?> clazz, String fieldAlias) {
Field[] fields = DeclaredFields();
for (Field field : fields) {
if (Annotation(XStreamCDATA.class) != null) {
XStreamAlias xStreamAlias = Annotation(XStreamAlias.class); if (xStreamAlias != null && fieldAlias.equals(xStreamAlias.value())) { return true;
} else {
if (fieldAlias.Name())) {
return true;
}
伐地考昔
}
}
}
return false;
}
}
三、创建⼯具类
public class XmlUtils {
private static final XStream xStream = XStream();
/**
* 对象转xml
* @param obj 对象
* @return
*/
public static String toXml(Object obj) {
xStream.Class());
XML(obj);
}
}
四、创建对象类
由于最近在做开发,直接就拿⼀个类来做演⽰。字段添加@XStreamCDATA注解:
@XStreamAlias("xml")
public class WechatOutTextMsg implements Serializable {
private static final long serialVersionUID = -1883441132514476532L;
/**
* 接收⽅账号(收到的OpenID)
*/
@XStreamAlias("ToUserName")
@XStreamCDATA
private String toUserName;
/**
* 开发者号
*/
@XStreamAlias("FromUserName")
@XStreamCDATA
private String fromUserName;
/**
* 消息创建时间(整形)
*/
@XStreamAlias("CreateTime")
private Long createTime;鹿头标本
/**
* 消息类型
*/
@XStreamAlias("MsgType")按摩腰靠
@XStreamCDATA
private String msgType;
/**
* 回复的消息内容
*/
@XStreamAlias("Content")
@XStreamCDATA
private String content;
导线弧垂计算公式//Getter
}
五、测试
public class XmlUtilsTest {
@Before
public void before() throws Exception {
}
@After
public void after() throws Exception {
}
/**
*
* Method: toXml(Object obj)
*
*/
@Test
public void testToXml() throws Exception {
WechatOutTextMsg outTextMsg = new WechatOutTextMsg(); outTextMsg.setContent("你好");
outTextMsg.setCreateTime((new Date()).getTime());
outTextMsg.setFromUserName("fromUserName");
outTextMsg.setMsgType("text");
outTextMsg.setToUserName("toUserName");
//转xml
String str = Xml(outTextMsg);
System.out.println(str);
}
}
结果输出
<xml>
<ToUserName><![CDATA[toUserName]]></ToUserName>
<FromUserName><![CDATA[fromUserName]]></FromUserName> <CreateTime>1511358600000</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>