用来记录一些原创性的总结
在上文介绍了文本标签如果内容中包含了XML元素时会自动的被JAXB进行转译。示例代码如下:
@Test
public void testMarshal() {
Response response = new Response();
response.setCode(200);
response.setMessage("success");
response.setReturnValue("<a><b>123</b></a>");
JAXB.marshal(response, System.out);
}
@XmlRootElement
public static class Response {
private int code;
private String message;
private String returnValue;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getReturnValue() {
return returnValue;
}
public void setReturnValue(String returnValue) {
this.returnValue = returnValue;
}
}
输出如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<code>200</code>
<message>success</message>
<returnValue><a><b>123</b></a></returnValue>
</response>
我们可以看到returnValue属性值<a><b>123</b></a>
被成功的转译了。JAXB对标签转译是通过com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler
实现类来进行的,默认的实现类是会对标签进行转译的。所以我们只需要实现自己的com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler
,然后在实现中对文本不进行转译即可。为此定义了如下这样一个CharacterEscapeHandler
。
@SuppressWarnings("restriction")
public static class MyCharacterEscapeHandler implements com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler {
public static final MyCharacterEscapeHandler INSTANCE = new MyCharacterEscapeHandler();
private MyCharacterEscapeHandler() {
}
@Override
public void escape(char[] chars, int start, int length, boolean isAttVal, Writer out) throws IOException {
//直接输出文本即可,即原样输出,默认实现,这里是会进行转译的。
out.write(chars, start, length);
}
}
然后需要用它来替换掉默认实现。在下面代码中通过marshaller.setProperty("com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler", MyCharacterEscapeHandler.INSTANCE);
这句实现的。
@Test
public void testMarshal() throws Exception {
Response response = new Response();
response.setCode(200);
response.setMessage("success");
response.setReturnValue("<a><b>123</b></a>");
JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//替换默认的CharacterEscapeHandler实现为我们自己的实现
marshaller.setProperty("com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler", MyCharacterEscapeHandler.INSTANCE);
marshaller.marshal(response, System.out);
}
之后再次对之前的对象进行marshal时将输出如下内容。我们可以看到这个时候我们的returnValue的值没有再被转译了。但是它在被应用时如果需要转换为Response对象是走不通的,这在之前的《JAXB系列之通过XmlJavaTypeAdapter自动加上CDATA》一问中有说明。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<code>200</code>
<message>success</message>
<returnValue><a><b>123</b></a></returnValue>
</response>
(本文由Elim写于2017年7月29日)