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

 

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

 

分三步走:框架

 

 

首先建立适配器类:CDataAdapter.javaide

 

package com.zhaoyx;工具

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

//有时候 Java 类不能天然映射到本身所需的 XML 形式,this

//这时须要编写本身的适配器类,经过注解绑定到javabean的成员变量上,spa

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

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

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

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>

相关文章
相关标签/搜索