JAXB控制CDATA节点转义

参看:http://liugang594.iteye.com/blog/1981726

参看:http://blog.csdn.net/qustmeng/article/details/53706657


       在使用JAXB,将对象转换成xml时,有时会遇到节点需要包含<![CDATA[...]]>的情况,至于为什么要加<![CDATA[..]]>,这里就不再详述了。今天讨论在使用JAXB时,如何使对象属性值在转换到xml文件中时,会用<![CDATA[..]>包装。

       特别说明,本方法并不是唯一的解决该问题的方法。

       第一步:实现自定义的XmlAdaper<String, Stirng>, 比例自定义的类名为CDATASectionAdapter,CDATASectionAdapter的作用就是在写到xml文件之前,为属性值添加上“<![CDATA[ ]]>”。实现代码如下:

public class CDATASectionAdapter extends XmlAdapter<String, String> {  
  
    @Override  
    public String unmarshal(String v) throws Exception {  
        return v;  
    }  
  
    @Override  
    public String marshal(String v) throws Exception {  
        if(v != null){  
            return "<![CDATA["+v+"]]>";  
        }  
        return null;  
    }  
  
}  

    第二步,为需要加CDATA标记的类属性添加@XmlJavaTypeAdapter注解,该注解的作用就是标记该属性在转换到xml中或从xml中解析时,调用一个Adapter类的方法,这个Adapter就是指我们上面实现的CDATASectionAdapter类,具体写法示例:

@XmlElement(name="name")  
@XmlJavaTypeAdapter(CDATASectionAdapter.class)  
protected String name;
    注:上述代码,就是让属性name,在转换时调用CDATASectionAdapter类中的转换方法。因此,这样就可以为name属性值包装上“<![CDATA[ ..]]>”。


    至此,输出的xml文件中name属性已经被加上了CDATA的包装,只是“<”和“>”会被转义,"<"被转义为“&lt;”, ">"被转义为"&gt;",所以xml中的显示结果可能为:

<name><&lt;![CDATA[Bob]]&gt;</name>  

    因此,我们要消除转义,换句话说,就是阻止JAXB进行的转义动作。这就是第三步的任务。

   第三步,实现自定义的CharacterEscapeHandler类,拦截JAXB的转义动作。(由于该类过于简单,没必要创建新的文件,直接定义成匿名内部类,如第四步示例所示)

   第四步,在将对象转换成xml时,会用到Marshaller对象,调用该对象的setProperty方法,注入第三步中实现的类,控制转换时不进行转义,例如:

try {  
    JAXBContext context = JAXBContext.newInstance(obj.getClass());  
    Marshaller marshaller = context.createMarshaller();  
    
	// xml格式  
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
   
    // 不进行转义字符的处理  
    marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() {  
           public void escape(char[] ch, int start,int length, boolean isAttVal, Writer writer) throws IOException {  
               writer.write(ch, start, length);  
           }  
         });  
    StringWriter sw = new StringWriter();  
	marshaller.marshal(obj, sw);  
    return sw.toString();  
} catch (JAXBException e) {  
    log.error("", e);  
}
注:上述代码中用到的CharacterEscapeHandler类是CharacterEscapeHandler为com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler。

注:所谓的拦截,就是上述匿名内部类重载的escape方法,不做其他动作,只是将输入参数传递到writer中。




  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值