JAXB将JAVA对象转换为XML时CDATA的问题
来源:互联网 发布:爱淘宝推广 编辑:程序博客网 时间:2024/05/18 00:44
对Java对象转换为xml字符串时,如果有特殊字符如<>必须要是用<![CDATA[]]>来声明。我先尝试了使用XStream解决这个问题也有使用MOXy CDATA注解解决,最后发现,都存在一定的缺陷,甚至不能正常的实现该功能。
最终解决方案有两个,都可以解决这个问题,但是第一个方案由于引用了sun的专有API,在编译时会存在警告,使用了内部的API并不是值得推荐的。但是这里也贴出来,供大家参考。
sunAPI版:
首先继承XMLSerializer
import com.sun.org.apache.xml.internal.serialize.OutputFormat;import com.sun.org.apache.xml.internal.serialize.XMLSerializer;import org.xml.sax.SAXException;import java.io.OutputStream;import java.util.regex.Pattern;public class CDataContentHandler extends XMLSerializer { private static final Pattern XML_CHARS = Pattern.compile("[<>&]"); public CDataContentHandler( OutputStream output, OutputFormat format ) { super(output,format); } public void characters(char[] ch, int start, int length) throws SAXException { boolean useCData = XML_CHARS.matcher(new String(ch, start, length)).find(); if (useCData) super.startCDATA(); super.characters(ch, start, length); if (useCData) super.endCDATA(); }}
实际的转换方法:
public static String ojbectToXmlWithCDATA(Class clazz, Object obj) throws Exception {JAXBContext context = JAXBContext.newInstance(clazz);OutputFormat of = new OutputFormat();of.setOmitXMLDeclaration(true);of.setPreserveSpace(true);of.setIndenting(true);ByteArrayOutputStream op = new ByteArrayOutputStream();CDataContentHandler serializer = new CDataContentHandler(op, of);SAXResult result = new SAXResult(serializer.asContentHandler());Marshaller mar = context.createMarshaller();mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);mar.marshal(obj, result);return op.toString("UTF-8");}
第二个方法是目前使用的方法,参考了一个国外同行的解决方法,这个解决方案将自定实现javax.xml.stream.xmlstreamwriter,没有第三方的库依赖:
执行类决定哪些地方需要添加CDATA:
import javax.xml.stream.XMLStreamException;import javax.xml.stream.XMLStreamWriter;import java.util.regex.Pattern; /** * Implementation which is able to decide to use a CDATA section for a string. */public class CDataXMLStreamWriter extends DelegatingXMLStreamWriter{ private static final Pattern XML_CHARS = Pattern.compile( "[&<>]" ); public CDataXMLStreamWriter( XMLStreamWriter del ) { super( del ); } @Override public void writeCharacters( String text ) throws XMLStreamException { boolean useCData = XML_CHARS.matcher( text ).find(); if( useCData ) { super.writeCData( text ); } else { super.writeCharacters( text ); } }}
委托类:
import javax.xml.namespace.NamespaceContext;import javax.xml.stream.XMLStreamException;import javax.xml.stream.XMLStreamWriter; /** * Delegating {@link XMLStreamWriter}. */abstract class DelegatingXMLStreamWriter implements XMLStreamWriter{ private final XMLStreamWriter writer; public DelegatingXMLStreamWriter( XMLStreamWriter writer ) { this.writer = writer; } public void writeStartElement( String localName ) throws XMLStreamException { writer.writeStartElement( localName ); } public void writeStartElement( String namespaceURI, String localName ) throws XMLStreamException { writer.writeStartElement( namespaceURI, localName ); } public void writeStartElement( String prefix, String localName, String namespaceURI ) throws XMLStreamException { writer.writeStartElement( prefix, localName, namespaceURI ); } public void writeEmptyElement( String namespaceURI, String localName ) throws XMLStreamException { writer.writeEmptyElement( namespaceURI, localName ); } public void writeEmptyElement( String prefix, String localName, String namespaceURI ) throws XMLStreamException { writer.writeEmptyElement( prefix, localName, namespaceURI ); } public void writeEmptyElement( String localName ) throws XMLStreamException { writer.writeEmptyElement( localName ); } public void writeEndElement() throws XMLStreamException { writer.writeEndElement(); } public void writeEndDocument() throws XMLStreamException { writer.writeEndDocument(); } public void close() throws XMLStreamException { writer.close(); } public void flush() throws XMLStreamException { writer.flush(); } public void writeAttribute( String localName, String value ) throws XMLStreamException { writer.writeAttribute( localName, value ); } public void writeAttribute( String prefix, String namespaceURI, String localName, String value ) throws XMLStreamException { writer.writeAttribute( prefix, namespaceURI, localName, value ); } public void writeAttribute( String namespaceURI, String localName, String value ) throws XMLStreamException { writer.writeAttribute( namespaceURI, localName, value ); } public void writeNamespace( String prefix, String namespaceURI ) throws XMLStreamException { writer.writeNamespace( prefix, namespaceURI ); } public void writeDefaultNamespace( String namespaceURI ) throws XMLStreamException { writer.writeDefaultNamespace( namespaceURI ); } public void writeComment( String data ) throws XMLStreamException { writer.writeComment( data ); } public void writeProcessingInstruction( String target ) throws XMLStreamException { writer.writeProcessingInstruction( target ); } public void writeProcessingInstruction( String target, String data ) throws XMLStreamException { writer.writeProcessingInstruction( target, data ); } public void writeCData( String data ) throws XMLStreamException { writer.writeCData( data ); } public void writeDTD( String dtd ) throws XMLStreamException { writer.writeDTD( dtd ); } public void writeEntityRef( String name ) throws XMLStreamException { writer.writeEntityRef( name ); } public void writeStartDocument() throws XMLStreamException { writer.writeStartDocument(); } public void writeStartDocument( String version ) throws XMLStreamException { writer.writeStartDocument( version ); } public void writeStartDocument( String encoding, String version ) throws XMLStreamException { writer.writeStartDocument( encoding, version ); } public void writeCharacters( String text ) throws XMLStreamException { writer.writeCharacters( text ); } public void writeCharacters( char[] text, int start, int len ) throws XMLStreamException { writer.writeCharacters( text, start, len ); } public String getPrefix( String uri ) throws XMLStreamException { return writer.getPrefix( uri ); } public void setPrefix( String prefix, String uri ) throws XMLStreamException { writer.setPrefix( prefix, uri ); } public void setDefaultNamespace( String uri ) throws XMLStreamException { writer.setDefaultNamespace( uri ); } public void setNamespaceContext( NamespaceContext context ) throws XMLStreamException { writer.setNamespaceContext( context ); } public NamespaceContext getNamespaceContext() { return writer.getNamespaceContext(); } public Object getProperty( String name ) throws IllegalArgumentException { return writer.getProperty( name ); }}
示例方法:
/**使用JAXB方式解决CDATA问题 * * @throws Exception */ public static String ojbectToXmlWithCDATA(Class clazz, Object obj) throws Exception { JAXBContext context = JAXBContext.newInstance(clazz); ByteArrayOutputStream op = new ByteArrayOutputStream(); XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter streamWriter = xof.createXMLStreamWriter(op); CDataXMLStreamWriter cdataStreamWriter = new CDataXMLStreamWriter(streamWriter); Marshaller mar = context.createMarshaller(); mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); mar.marshal(obj, cdataStreamWriter); cdataStreamWriter.flush(); cdataStreamWriter.close(); return op.toString("UTF-8"); }
生成后的xml代码示例:
<?xml version='1.0' encoding='utf-8'?><businessMessages xmlns="http://aaa.xxx.com/schema/BusinessMessages"> <businessMessage> <uuid>abcccc</uuid> <source>tms</source> <topic>type</topic> <bussinessNo>123</bussinessNo> <header></header> <body> <![CDATA[<pivotFlow xmlns="http://aaa.xxx.com/schema/PivotFlow"><orderId>112345</orderId><operPersonId>testOper</operPersonId><operTime>2016-02-16T16:13:40.364+08:00</operTime><status>testType</status><appendix>{"shipper":"testShip","carrierPhone":"1860132223","carrier":"testCarr"}</appendix></pivotFlow>]]></body> </businessMessage></businessMessages>
英文原文参考:http://blog.mi-ernst.de/2012/05/04/jaxb-and-cdata-sections/
博客来源:http://blog.csdn.net/wantken/article/details/50675549
1 0
- JAXB将JAVA对象转换为XML时CDATA的问题
- JAXB将JAVA对象转换为XML时CDATA的问题
- 用JAXB转换XML和Java对象时的循环引用问题的解决方法
- JAXB解析xml文件转换为Java对象
- xml-xml与java对象之间的转换(jaxb)
- Jaxb实现Java对象与XML之间的转换
- [转载] JAXB中Java对象跟XML之间的转换
- JAXB中Java对象和XML之间的转换
- 利用JAXB实现java对象和xml的相互转换
- JAXB实现JAVA对象和XML字符串的互相转换
- JAXB 可以实现Java对象与XML的相互转换
- JAXB-java对象和xml相互转换
- java对象和xml之间转换--Jaxb
- Jaxb将xml转换为bean时异常javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"
- 通过JAXB将对象与XML相互转换
- 基于JAXB实现将vo对象转化为xml字符串
- JAVA对象转换成XML(<![CDATA[文本内容]]>)
- Xml与Java Object 的转换[JAXB]
- app 上架发布
- 返回顶部按钮
- 计算图像直方图方法,纠正calcHist调用错误(OpenCV)
- AngularJS中星级的评价(ionic)
- 什么才是动力电池管理系统(BMS)的核心技术?
- JAXB将JAVA对象转换为XML时CDATA的问题
- 驱动程序调试(二)————根据内核打印的段错误信息分析
- html()、text()、val()方法区别
- ES6--Promise、Generator及async
- FTP文件传输协议详解
- Eureka与ZooKeeper 的比较
- Pixhawk-飞控平台
- 读取word模板,并写入数据到word文件中
- 64位CentOS 6.7安装Caffe (非GPU模式 )