三步解決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>

相關文章
相關標籤/搜索