zoukankan      html  css  js  c++  java
  • 不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller

    摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现。然而在现实中“不规矩”的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧,调整一下思维便能重用Marshaller了,征服它们使工作更简单
    关键词:Marshaller, JAVA, XML

     
    将一个类生成一个Json字符串、将一个Json字符串翻译成一个类(JAVA、C#代码),这一过程已经在“”博客中描述了;在实际项目应用中,如何将一个类生成一个XML文档或XML字符串,如何将一个XML文档翻译成一个类,这又是经常遇到的问题。比如,跟其它系统的交互中,其它系统定义的接口参数以XML格式定义,那么你写的系统就要解析并理解它传入的数据,或者把自己内部的数据转成按它规定的XML格式文档传出。在JAVA里,这一过程还蛮简单,使用Marshaller便可以很轻松的解决。
     
    然而,有一些“不守规矩”的XML格式可能被其它系统定义了,它们定义的XML格式恰恰不是Marshaller天生有能力生成与解析的,我们对这种“不规矩"的XML就无计可施了吗?其实Marshaller还是很好用的,后来你会发现Marshaller的极限便不复存在。下面,我以一个简单的例子来证明我的这一观点,对于“不规矩”的XML我也是有办法将其制服的。
     
    一、XML帮助类
     
    首先,你得有一个XML帮助类,它提供的是最基础的,使用Marshaller使XML和JAVA对象互转,这对于规矩的XML文档们,便能以一挡百了。
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
     
    /**
     * XML的帮助类
     * 
     * @author wanganqi
     * @version v1.0
     * @since 2014年8月13日下午2:38:52
     */
    public class XmlHelper
    {
        /**
         * 将自定义数据对象转化为XML字符串
         * 
         * @param clazz 自定义数据类型
         * @param object 自定义数据对象
         * @return XML字符串
         * @throws JAXBException 异常
         */
        public static String objectToXML(Class clazz, Object object)
            throws JAXBException
        {
            String xml = null;
            JAXBContext context = JAXBContext.newInstance(clazz);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            Writer w = new StringWriter();
            m.marshal(object, w);
            xml = w.toString();
            return xml;
        }
     
        /**
         * 将XML字符串转化为自定义数据对象
         * 
         * @param clazz 自定义数据类型
         * @param xml XML字符串
         * @return 自定义数据对象
         * @throws JAXBException 异常
         */
        public static Object xmlToObject(Class clazz, String xml)
            throws JAXBException
        {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller um = context.createUnmarshaller();
            return um.unmarshal(new StringReader(xml));
        }
    }
     
    ​这对于这样规矩的:XML,就要定义这样的:JAVA类,一一对应,什么事情都能解决。
     
    XML(规矩的)文件格式样例 JAVA生成方法
    <?xml version="1.0" encoding="UTF-8"?>
    <ANQIFILE>
        <HEAD>
            <ANQINUM>2</ANQINUM>
            <DATETIME>YYYY-MM-DD HH:MM:SS</DATETIME>
            <APPROVALNUM>王安琪No1</APPROVALNUM>
        </HEAD>
        <BODY>
            <ANQI>00001</ANQI>
            <ANQI>00002</ANQI>
            <ANQI>00003</ANQI>
        </BODY>
    </ANQIFILE>
    ANQIHead head = new ANQIHead(1, "YYYY-MM-DD HH:MM:SS", "王安琪No1");
    ANQIBody body = new ANQIBody("00001", "00002", "00003");
    ANQIFile anqiFile = new ANQIFile(head, body);
    String xml = XmlHelper.objectToXML(ANQIFile.class, anqiFile);

    补充说明:
    下面的构造函数都隐去了,使用
     String... anqis类似的参数,使用时请不要疑惑。
    @XmlRootElement(name = "ANQIFILE")
    @XmlType(propOrder = "head""body" })
    public class ANQIFile
    {
        private ANQIHead head;
     
        private ANQIBody body;
     
        
     
        @XmlElement(name = "HEAD")
        public ANQIHead getHead()
        {
            return head;
        }
     
        public void setHead(ANQIHead head)
        {
            this.head = head;
        }
     
        @XmlElement(name = "BODY")
        public ANQIBody getBody()
        {
            return body;
        }
     
        public void setBody(ANQIBody body)
        {
            this.body = body;
        }
    }
    -------------------------------------------------------------------------------------
    public class ANQIBody
    {
     
        private List<String> anqi;
     
        
     
        @XmlElement(name = "ANQI")
        public List<String> getAnqi()
        {
            return anqi;
        }
     
        public void setAnqi(List<String> anqi)
        {
            this.anqi = anqi;
        }
    }
    @XmlType(propOrder = "anqiNum""dateTime""appovalNum" })
    public class ANQIHead
    {
     
        private int anqiNum;
        private String dateTime;
        private String appovalNum;
     
        
     
        @XmlElement(name = "ANQINUM")
        public int getAnqiNum()
        {
            return clueNum;
        }
     
        public void setAnqiNum(int clueNum)
        {
            this.clueNum = clueNum;
        }
     
        @XmlElement(name = "DATETIME")
        public String getDateTime()
        {
            return dateTime;
        }
     
        public void setDateTime(String dateTime)
        {
            this.dateTime = dateTime;
        }
     
        @XmlElement(name = "APPROVALNUM")
        public String getAppovalNum()
        {
            return appovalNum;
        }
     
        public void setAppovalNum(String appovalNum)
        {
            this.appovalNum = appovalNum;
        }
    }

    补充说明:
    这里的构造函数都隐去了,使用
    String... anqis类似的参数,使用时请不要疑惑。
     
     
    二、将 自定义数据对象 与 XML(不规矩的)字符串 互转
     
    现在我们有一个需求,把我们系统的JAVA对象转成按其它系统规定的XML格式文档传出,其它系统给了我们一份XML格式文档,希望我们能正确构造它;我写的系统要解析并理解其它系统传入的XML数据,同样的其它系统给了我们一份XML格式文档,希望我们能顺利解释它。看看我们是怎么做的吧。
    XML格式:
    XML(不规矩的)文件格式样例 JAVA使用方法 及 JAVA类
    <?xml version="1.0" encoding="UTF-8"?>
    <ANGELFILE>    
        <ANGEL>
            <WANG ID="00001" COUNT="2">
                <ANQI>
                    <ITEM1>VALUE</ITEM1>
                    <ITEM2>VALUE</ITEM2>
                    <ITEMN>VALUE</ITEMN>
                </ANQI>
                <ANQI>
                    <ITEM1>VALUE</ITEM1>
                    <ITEM2>VALUE</ITEM2>
                    <ITEMN>VALUE</ITEMN>
                </ANQI>
            </WANG>
        </ANGEL>
    </ANGELFILE>
    可以使用与上面规矩的XML类似的JAVA定义、使用方法。
     
    现在看看它有多不规矩(其实也不是很不规矩啦,只是在ANQI这个节点下面的子节点名字每个都不一样,但都是以ITEM开头的)。
    要生成这样的XML,可以先用ObjectToXML()生成都是以 ITEM 命名的节点,再通过DOM读取并更新ITEM名称,后面加上1、2...
    要解析这样的XML,可以先把此XML过滤一遍,把ITEM*样的节点名称更新为 ITEM,再用XMLToObject()生成对象。
     
    三、遇到的问题及改进方法
     
    1、在使用Marshaller过程中,出现了一点问题:生成XML时,并不按照配置的@XmlType(propOrder = "1""2" })的顺序,而是恰好相反的,这个问题目前还没有解决,唯一在网上查到的相关信息是说JAVA版本为6以下的会有这个BUG,但是我的JAVA版本为1.7,也出现了这个问题,望有知道解决方法的同学告知一下,不吝赐教

    2、对于不规矩的XML格式,更好的办法是使用Marshaller所支持的自定义解析器,上面的不规矩XML完全可以映射到Map对象上面去。这种方法更能支持更不规则的XML定义。网上不知有无已经实现的代码,知道的同学,不吝赐教

    最近项目工作量很大,每天都能学习到很多东西,项目管理的、JAVA使用的、界面规范的......不胜枚举,毕竟是第一次自己负责的项目,经验和教训肯定的巨大的。

    作为一个项目经理,对作品、对自己的团队都觉得立马有了深深的责任感,也有了很大的压力,感谢组织的信任与支持,感谢团队的鼎力协作,感谢相关部门的大力配合,感谢姚老师的无私帮助,也感谢老婆默默的支持。

    ありがとうございます 

    如何集中资源做成一个优秀的项目,如何担当得起自己的责任,如何与各类角色沟通,真是任重而道远。





  • 相关阅读:
    [Sqlite] 移动嵌入式数据库Sqlite日报SQL操作语句汇总
    Matlab spline
    读书笔记:《重来REWORK》
    读书笔记:《一生的计划》
    6 款好用的 PC+Android 同步 GTD 软件
    第35本:《像外行一样思考,像专家一样实践》
    第34本:《暗时间》
    第33本:《删除:大数据取舍之道》
    第32本:《超级时间整理术----每天多出一小时》
    第31本: 思考的乐趣
  • 原文地址:https://www.cnblogs.com/wgp13x/p/3995368.html
Copyright © 2011-2022 走看看