三步解决JAXB生成XML包含CDATA问题

废话不多说,写此文档的目的就是为了帮助java开发者,解决利用JAXB生成XML时,XML中带有CDATA问题。

分三步走:

首先创建适配器类:CDataAdapter.java

package com.zhaoyx;

import javax.xml.bind.annotation.adapters.XmlAdapter;

//有时候 Java 类不能自然映射到自己所需的 XML 形式,

//这时需要编写自己的适配器类,通过注解绑定到javabean的成员变量上,

//在运行的时候jaxb框架自动会适配你所编写的适配器类的方法

//CDataAdapter.marshal(String str),将javabean的成员变量的value值

//转变成你想要的形式。

public class CDataAdapter extends XmlAdapter<String,String> {

//从javabean到xml的适配方法

@Override
public String marshal(String str) throws Exception {
return "<![CDATA[" + str+ "]]>";
}

//从xml到javabean的适配方法
@Override
public String unmarshal(String str) throws Exception {
return str;
}
}

其次创建JAXB生成XML的工具类:JaxbToXmlUtil.java

package com.zhaoyx;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

//这里用到了JAXB的核心类和方法,不懂可以去查看下JAXB基础应用,

//这里只做关键解释。

public class JaxbToXmlUtil {

public static String convertToXml(Object obj,String encoding) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
marshaller.setProperty(Marshaller.JAXB_ENCODING,encoding);

//去掉生成xml的认报文头。
marshaller.setProperty(Marshaller.JAXB_FRAGMENT,true);

//转换所有的适配字符,包括xml实体字符&lt;和&gt;,xml实体字符在好多处理xml

//的框架中是处理不了的,除非序列化。
marshaller.setProperty("com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler",
new CharacterEscapeHandler() {
@Override
public void escape(char[] ch,int start,int length,boolean isAttVal,
Writer writer) throws IOException {
writer.write(ch,start,length);
}
});

StringWriter writer = new StringWriter();

//添加自己想要的xml报文头
writer.write("<?xml version=\'1.0\' encoding=\'" + encoding + "\'?>\n");
marshaller.marshal(obj,writer);
result = writer.toString();
} catch (JAXBException e) {
e.printstacktrace();
}

return result;
}
}

最后创建用于转换成XML文件的javabean:Root.java

package com.zhaoyx;

import javax.xml.bind.annotation.XmlAccesstype;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccesstype.FIELD)
public class Root {

//绑定自己的适配器类,适配希望包含在CData数据块中的javabean成员变量。

//这里的空值是为了测试,无其他涵义。

@XmlJavaTypeAdapter(CDataAdapter.class)
private String name = "";

@XmlJavaTypeAdapter(CDataAdapter.class)
private String surname;

private String id;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSurname() {
return surname;
}

public void setSurname(String surname) {
this.surname = surname;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

}

上面三步就可以解决利用JAXB生成XML时,XML中包含CDATA数据块的问题。

下面是用于测试的类:JaxbTest.java

package com.zhaoyx;


public class JaxbTest {

public static void main(String[] arg) {

Root root = new Root();
root.setId("ddd");
root.setSurname("jiiii");

//由于在javabean中赋值为空,这句可以不要,也可以去掉javabean中的赋空值语句
root.setName("");
String str = JaxbToXmlUtil.convertToXml(root,"GBK");
System.out.println(str);
}

}

控制台输出结果:

<?xml version='1.0' encoding='GBK'?> <root> <name><![CDATA[]]></name> <surname><![CDATA[jiiii]]></surname> <id>ddd</id> </root>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇