摘要:将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使用的、界面规范的......不胜枚举,毕竟是第一次自己负责的项目,经验和教训肯定的巨大的。

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

ありがとうございます 

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

来自王安琪

转载于:https://www.cnblogs.com/wgp13x/p/3995368.html

不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller相关推荐

  1. java非闭合xml转对象,不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller

    摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中"不规矩"的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧, ...

  2. 使用castor实现xml和java对象的转换

    对于xml和java对象的转换这里用castor进行转换,当然还有别的方式 方式一:castor和xml映射文件配合 首先提供需要解析的XML(内容不重要,重要的是格式) <?xml versi ...

  3. xml与java对象互转

    摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中"不规矩"的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧, ...

  4. 用 XStream 序列化/反序列化 XML 为 Java 对象(实例)

    用 XStream 序列化/反序列化 XML 为 Java 对象(实例) Posted on 2007-06-05 19:06 Stephen Wong 阅读(1224) 评论(0)  编辑 收藏 网 ...

  5. java xml amp_Javaamp;Xml教程(十一)JAXB实现XML与Java对象转换

    JAXB是Java Architecture for XML Binding的缩写,用于在Java类与XML之间建立映射,可以帮助开发人员非常方便的將XML和Java对象进行相互转换. 本文以一个简单 ...

  6. digester java_利用Digester把XML转换为Java对象

    在一个比较完整的应用系统里,经常需要有一些配置文件.简单的属性使用.properties文件即可,但要配置一些复杂对象,则应该考虑使用xml文件.一般用来读取xml文件的工具包有DOM.SAX和JDO ...

  7. digester java_[jakarta-commons] 使用Digester解释xml获取java对象(代码入注规则 或 配置规则 任你选!)...

    # re: [jakarta-commons] 使用Digester解释xml获取java对象(代码入注规则 或 配置规则 任你选!) 2009-11-09 10:27 | Java小子 楼主,运行起 ...

  8. JavaXml教程(十一)JAXB实现XML与Java对象转换

    JAXB是Java Architecture for XML Binding的缩写,用于在Java类与XML之间建立映射,能够帮助开发者很方便的將XML和Java对象进行相互转换. 本文以一个简单的例 ...

  9. Json对象与Json字符串的转化、JSON字符串与Java对象的转换

    一.Json对象与Json字符串的转化 1.jQuery插件支持的转换方式: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符 ...

  10. json java typeof_Json对象与Json字符串的转化、JSON字符串与Java对象的转换

    一.Json对象与Json字符串的转化 1.jQuery插件支持的转换方式: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符 ...

最新文章

  1. 什么是数据库范式(NF)?从一范式到五范式分别是什么?
  2. 什么是数据库负载均衡
  3. OpenVAS漏洞扫描基础教程之创建用户
  4. Java 最多能买到的笔数
  5. mysql一张表两个索引字段是建两颗独立索引树吗?
  6. Linux 查看CPU信息,内存等信息
  7. Ubuntu关闭anaconda自动进入base虚拟环境
  8. Andorid之打包出现Proguard returned with erro code 1.See console解决办法
  9. 我们常常怕打扰别人,而忽略要打个电话问候对方,
  10. redis实现可重入锁
  11. 文成小盆友python-num6 -反射 ,常用模块
  12. 输入身份证自动回填地址,年龄,个人详细信息
  13. lammps后处理:Python调用Ovito模块配置方法
  14. php 模拟登陆微信,PHP微信模拟登陆并给用户发送消息的方法
  15. FastDb 简单编码运用
  16. 程序员如何站在巨人的肩膀上
  17. ValueError: Wrong number of items passed 2, placement implies 1
  18. iOS常见错误1-SQLite错误-SQLITE_CANTOPEN,SQLITE_MISUSE和SQLITE_BUSY
  19. VS中进行C#编码时智能提示由英文切换为中文
  20. 如何设置和取消Mac电脑的开机密码?

热门文章

  1. asp.net core 支付宝支付( 电脑2.0)
  2. 关于python最大递归深度 - 998
  3. JavaScript文本收缩展开 showdetail
  4. Javascript 学习之路:鼠标长按事件
  5. 不用代码隐藏自定义列表
  6. gnome 3.4 评测
  7. 有趣的视频 国外计算机课程
  8. Identity Server 4 - Hybrid Flow - MVC客户端身份验证
  9. 通过Keepalived实现Redis Failover自动故障切换
  10. DDK nmake : error 解决方法