jaxb实现xml与bean的相互转化

jaxb使用完整例子

  这里边有提到 MessageFormat,可以了解下。下边还有一个其他博客粘过来的几行代码,记录一下。

  附上几个链接    [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换     JAXB生成CDATA类型的节点    Jaxb如何优雅的处理CData

 我这里以《书》为例,写一个完整的测试代码,xml包含了各种元素和集合。

 test.xml

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<book id="1234567890" name="寻医不如自医">
    <author>陈金柱</author>
    <press>金城出版社</press>
    <main_info>
        <chapters_num>5</chapters_num>
        <editor>王景涛</editor>
        <pub_time>2017-01-01</pub_time>
    </main_info>
    <chapters>
        <chapter>
            <num>1</num>
            <name>你所不知道的事</name>
        </chapter>
        <chapter>
            <num>2</num>
            <name>人体中有哪些重要的部分</name>
        </chapter>
        <chapter>
            <num>3</num>
            <name>中医健康基础知识</name>
        </chapter>
    </chapters>
</book>

 实体类:

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
 * 书
 * 不指定顺序的时候是按英文字母排序的
 * propOrder指定顺序,里边填的是属性的名,不是注解里的name
 * 如果指定顺序的话,需要把所有属性都写里边,不然会报错
 * @author changxinzhi
 *
 */
@XmlRootElement(name = "book")
@XmlType(propOrder={"id","name","author","press","mainInfo","chapters"})
public class Book {    
    private String id;//图书ID
    private String name;//图书名称
    private String author;//作者
    private String press;//出版社
    private MainInfo mainInfo;//重要信息
    private List<Chapter> chapters;//章节信息
    
    @XmlAttribute(name = "id")
    public String getId() {
        return id;
    }    
    public void setId(String id) {
        this.id = id;
    }
    @XmlAttribute(name = "name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }    
    @XmlElement(name = "author")
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    @XmlElement(name = "press")
    public String getPress() {
        return press;
    }
    public void setPress(String press) {
        this.press = press;
    }
    @XmlElement(name = "main_info")
    public MainInfo getMainInfo() {
        return mainInfo;
    }
    public void setMainInfo(MainInfo mainInfo) {
        this.mainInfo = mainInfo;
    }
    @XmlElementWrapper(name = "chapters")
    @XmlElement(name = "chapter")
    public List<Chapter> getChapters() {
        return chapters;
    }
    public void setChapters(List<Chapter> chapters) {
        this.chapters = chapters;
    }
}
import javax.xml.bind.annotation.XmlRootElement;

/**
 * 书的重要信息
 * @author cxz
 */
@XmlRootElement(name = "main_info")
public class MainInfo {
    private String editor;//责任编辑
    private String pub_time;
    private String chapters_num;
    public String getEditor() {
        return editor;
    }
    public void setEditor(String editor) {
        this.editor = editor;
    }
    public String getPub_time() {
        return pub_time;
    }
    public void setPub_time(String pub_time) {
        this.pub_time = pub_time;
    }
    public String getChapters_num() {
        return chapters_num;
    }
    public void setChapters_num(String chapters_num) {
        this.chapters_num = chapters_num;
    }    
}
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
* 章节信息
* @author cxz
*/
@XmlRootElement(name="chapter")
@XmlType(propOrder={"num","name"})
public class Chapter {
    private String num;
    private String name;
    public String getNum() {
        return num;
    }
    public void setNum(String num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }     
}

工具类

import java.io.StringReader;
import java.io.StringWriter;
import java.text.MessageFormat;

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

/**
 * json使用alibaba.fastjson
 * @author cxz
 * Jaxb2.0 处理Xml与Object转换
 */
public class JaxbObjectAndXmlUtil {
    /**
     * 此处使用了Stringreader,其实Unmarshaller接口还支持
     * File,InputStream,URL,StringBuffer,org.w3c.dom.Node等反序列化
     * API连接
     * http://tool.oschina.net/uploads/apidocs/jdk-zh/javax/xml/bind/Unmarshaller.html
     * @param xmlStr 字符串
     * @param c 对象Class类型
     * @return 对象实例
     */
    @SuppressWarnings({ "unchecked", "finally" })
    public static <T> T xml2Object(String xmlStr,Class<T> c){ 
        try{ 
            JAXBContext context = JAXBContext.newInstance(c); 
            Unmarshaller unmarshaller = context.createUnmarshaller();              
            T t = (T) unmarshaller.unmarshal(new StringReader(xmlStr));              
            return t;              
        } catch (JAXBException e) {  
            e.printStackTrace();  return null; 
        }          
    } 
    
    /**
     * 可变参数
     * config里使用占位符 {0}  {1}  {2},单引号要使用两个
* MessageFormat使用链接 * @param config * @param c * @param arguments * @return */ @SuppressWarnings("unchecked") public static <T> T xml2Object(String config,Class<T> c,Object... arguments){ try{ if (arguments.length > 0) { config = MessageFormat.format(config, arguments); } JAXBContext context = JAXBContext.newInstance(c); Unmarshaller unmarshaller = context.createUnmarshaller(); T t = (T) unmarshaller.unmarshal(new StringReader(config)); return t; } catch (JAXBException e) { e.printStackTrace(); return null; } } /** * @param object 对象 * @return 返回xmlStr */ public static String object2Xml(Object object){ try{ StringWriter writer = new StringWriter(); JAXBContext context = JAXBContext.newInstance(object.getClass()); Marshaller marshal = context.createMarshaller(); marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化输出 marshal.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 编码格式,默认为utf-8 marshal.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml头信息 否
       

        //不进行转移字符的处理
//        marshal.setProperty(
//          "com.sun.xml.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);
//            }
//        });

            marshal.setProperty("jaxb.encoding", "utf-8"); 
            
            marshal.marshal(object,writer);
             
            return new String(writer.getBuffer());             
        }catch(Exception e){
            e.printStackTrace(); return null;
        }    
    }    
}

测试类

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;

public class test {
     /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args){
        //创建内容
        MainInfo mainInfo = new MainInfo();
        mainInfo.setEditor("王景涛");
        mainInfo.setPub_time("2017-01-01");
        mainInfo.setChapters_num("5"); 
        Chapter chapter1 = new Chapter();
        chapter1.setNum("1");
        chapter1.setName("你所不知道的事");        
        Chapter chapter2 = new Chapter();
        chapter2.setNum("2");
        chapter2.setName("人体中有哪些重要的部分");
        Chapter chapter3 = new Chapter();
        chapter3.setNum("3");
        chapter3.setName("中医健康基础知识");        
        Book book = new Book();
        List<Chapter> chapters = new ArrayList<Chapter>();
        chapters.add(chapter1);
        chapters.add(chapter2);
        chapters.add(chapter3);         
        book.setChapters(chapters);
        book.setMainInfo(mainInfo);
        book.setId("1234567890");
        book.setName("寻医不如自医");
        book.setAuthor("陈金柱");
        book.setPress("金城出版社");
        
        String xmlStr = JaxbObjectAndXmlUtil.object2Xml(book);//构造报文 XML 格式的字符串
        System.out.println("对象转xml报文: \n"+xmlStr);
        
        Book book2 = JaxbObjectAndXmlUtil.xml2Object(xmlStr, Book.class);
        System.out.println("报文转xml转: \n"+JSON.toJSONString(book2));
    }
}

 到这里已写完。

粘过来的几行代码,欢迎留言讨论。

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;

import org.apache.commons.lang.StringUtils;

/**
 * 使用Jaxb2.0实现XML<->Java Object的Binder.
 * StringUtils依赖commons-long包
 * 特别支持Root对象是List的情形.---??? ‘xml规范就是有且只有一个根元素’--不甚理解这里的做法
 * @author
 */
public class JaxbUtil {
    // 多线程安全的Context.
    private JAXBContext jaxbContext;
 
    /**
     * @param types  所有需要序列化的Root对象的类型.
     */
    public JaxbUtil(Class<?>... types) {
        try {
            jaxbContext = JAXBContext.newInstance(types);
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * Java Object->Xml.
     */
    public String toXml(Object root, String encoding) {
        try {
            StringWriter writer = new StringWriter();
            createMarshaller(encoding).marshal(root, writer);
            return writer.toString();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * Java Object->Xml, 特别支持对Root Element是Collection的情形.
     */
    @SuppressWarnings("unchecked")
    public String toXml(Collection root, String rootName, String encoding) {
        try {
            CollectionWrapper wrapper = new CollectionWrapper();
            wrapper.collection = root;
 
            JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(
                    new QName(rootName), CollectionWrapper.class, wrapper);
 
            StringWriter writer = new StringWriter();
            createMarshaller(encoding).marshal(wrapperElement, writer);
 
            return writer.toString();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * Xml->Java Object.
     */
    @SuppressWarnings("unchecked")
    public <T> T fromXml(String xml) {
        try {
            StringReader reader = new StringReader(xml);
            return (T) createUnmarshaller().unmarshal(reader);
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * Xml->Java Object, 支持大小写敏感或不敏感.
     */
    @SuppressWarnings("unchecked")
    public <T> T fromXml(String xml, boolean caseSensitive) {
        try {
            String fromXml = xml;
            if (!caseSensitive)
                fromXml = xml.toLowerCase();
            StringReader reader = new StringReader(fromXml);
            return (T) createUnmarshaller().unmarshal(reader);
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 创建Marshaller, 设定encoding(可为Null).
     */
    public Marshaller createMarshaller(String encoding) {
        try {
            Marshaller marshaller = jaxbContext.createMarshaller();
 
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 
            if (StringUtils.isNotBlank(encoding)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            }
            return marshaller;
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 创建UnMarshaller.
     */
    public Unmarshaller createUnmarshaller() {
        try {
            return jaxbContext.createUnmarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 封装Root Element 是 Collection的情况.
* xmlAnyType查到的东西不多,不太懂这个。
*/ public static class CollectionWrapper { @SuppressWarnings("unchecked") @XmlAnyElement protected Collection collection; } }

测试方法片段

        //写不写CollectionWrapper.class有什么区别,都可以正常运行
        //将java对象转换为XML字符串
        JaxbUtil requestBinder = new JaxbUtil(Hotel.class,CollectionWrapper.class);
        String retXml = requestBinder.toXml(hotel, "utf-8");
        System.out.println("xml:"+retXml);
        
        //将xml字符串转换为java对象
        JaxbUtil resultBinder = new JaxbUtil(Hotel.class,CollectionWrapper.class);
        Hotel hotelObj = resultBinder.fromXml(retXml);

 

posted @ 2018-12-24 17:01  常新志  阅读(1586)  评论(0编辑  收藏  举报