zoukankan      html  css  js  c++  java
  • 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报文: 
    "+xmlStr);
            
            Book book2 = JaxbObjectAndXmlUtil.xml2Object(xmlStr, Book.class);
            System.out.println("报文转xml转: 
    "+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);
  • 相关阅读:
    2015年个人记录
    Win10如何新建用户怎么添加新账户
    快速搭建一个本地的FTP服务器
    天气接口
    一张图搞定OAuth2.0
    PHP TS 和 NTS 版本选择
    如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
    Npm vs Yarn 之备忘详单
    浅谈CSRF
    值得看的cookie详解
  • 原文地址:https://www.cnblogs.com/xinzhisoft/p/10169594.html
Copyright © 2011-2022 走看看