`
zerozone
  • 浏览: 203790 次
  • 来自: 北京
社区版块
存档分类
最新评论

用Java实现Object对象树输出到XML文件

    博客分类:
  • Java
阅读更多
本文将结合面向对象设计原则实践来介绍如何将一个Java对象树输出到XML文件模块。

需求

项目功能:查询数据并生成XML文件然后上传至指定服务器
本模块功能:实现Java对象树输出到 XML文件。

要求
1. 支持对象及属性的扩展,而XML输出模块代码基本不变。
2. 考虑到内存压力,要求该模块实现以追加方式操作XML文件。

输入
Java对象树(提供一个类以方法,作为该对象的操作入口)

输出
XML文档

数值传输对象(DTO,Data Transfer Object),仅包含属性和setter/getter方法。如例1所示。属性的型别基本固定(例如String, int,boolean,List等),对于List的属性,可能包含另一个Java Object(如例3所示)。XML输出格式很简单,除去头部信息之外基本是attribute+value。例2是例1对象XML输出片段。

例1
java 代码
 
  1. public class FromTo{    
  2.     private String fromNo;    
  3.     private String toNo;    
  4.     private FromTo() { }    
  5.    
  6.     public void setFromNo(String fromNo){    
  7.           this.fromNo = fromNo;    
  8.     }    
  9.       
  10.      public String getFromNo() {    
  11.            return fromNo;    
  12.      }    
  13.            
  14.      public void setToNo(String toNo){    
  15.            this.toNo = toNo;    
  16.      }    
  17.           
  18.      public String getToNo() {    
  19.            return toNo;    
  20.      }    
  21. }    

例2
xml 代码
 
  1. <fromNo>DLS</fromNo>                
  2. <toNo>BJS</toNo>  

例3
java 代码
 
  1. public class CarrierFlight implements Serializable {    
  2.     /**  
  3.      *  
  4.      */    
  5.     private static final long serialVersionUID = 4295207854877905411L;    
  6.     private List apFlightNoList = new ArrayList(); //apFlightNoList存储FromTo类型的对象    
  7.     private List exFlightNoList = new ArrayList();  //同上    
  8.     private String carrierCode;    
  9.     private String rbd;    
  10.         
  11.     public CarrierFlight(){    }    
  12.         
  13.     /**  
  14.      * @param apFlightNoList  
  15.      */    
  16.     public void setApFlightNoList(List apFlightNoList) {    
  17.         this.apFlightNoList = apFlightNoList;    
  18.     }    
  19.         
  20.     /**  
  21.      * @return  
  22.      */    
  23.     public List getApFlightNoList() {    
  24.         return apFlightNoList;    
  25.     }    
  26.     
  27.     /**  
  28.      * @param apFlightNos  
  29.      */    
  30.     public void setApFlightNoList(ApFlightNo[] apFlightNos){    
  31.         if(!ArraysUtil.foreachable(apFlightNos))    
  32.             return;    
  33.         for(int i=0;i < apFlightNos.length;i++)  
  34.             this.apFlightNoList.add(apFlightNos[i];    
  35.     }    
  36.         
  37.     /**  
  38.       * @param exFlightNoList  
  39.       */    
  40.     public void setExFlightNoList(List exFlightNoList) {    
  41.        this.exFlightNoList = exFlightNoList;    
  42.     }    
  43.         
  44.     /**  
  45.      * @return  
  46.      */    
  47.     public List getExFlightNoList() {    
  48.        return exFlightNoList;    
  49.     }    
  50.         
  51.     /**  
  52.      * @param exFlightNos  
  53.      */    
  54.     public void setExFlightNoList(ExFlightNo[] exFlightNos){    
  55.         if(!ArraysUtil.foreachable(exFlightNos))    
  56.             return;    
  57.         for(int i=0;i < exFlightNos.length;i++)  
  58.            this.exFlightNoList.add(exFlightNos[i];    
  59.     }    
  60.         
  61.    /**  
  62.      * @param carrierCode  
  63.      */    
  64.     public void setCarrierCode(String carrierCode){    
  65.         this.carrierCode = carrierCode;    
  66.     }    
  67.         
  68.    /**  
  69.      * @return  
  70.      */    
  71.     public  String getCarrierCode(){    
  72.          return this.carrierCode;    
  73.     }    
  74.     
  75.    /**  
  76.      * @param rbd  
  77.      */    
  78.     public void setRBD(String rbd){    
  79.         this.rbd = rbd;    
  80.    }    
  81.   
  82.    /**  
  83.      * @return   
  84.      */    
  85.     public  String getRBD(){    
  86.          return this.rbd;    
  87.     }    
  88. }  

分析

先介绍一下XML输出模块的旧版本。它直接处理判断对象的类型,并显示获取其getter方法,得到属性的值后操作XML文档(即dom4j的Document)。如下所示
java 代码
 
  1. Object obj = getFromToObject();      
  2.            
  3. if(fromTo instanceof FromTo){      
  4.     FromTo fromto = (FromTo)obj;      
  5.     String fromNo = fromto.getFromNo();      
  6.     String toNo = fromto.getToNo();      
  7.     if(fromNo!=null && fromNo.length()>0){      
  8.          xml.output("<fromNo>"+fromNo+"</fromNo>");      
  9.     }      
  10.     if(toNo!=null && toNo.length()>0){      
  11.          xml.output("<toNo>"+toNo+"</toNo>");      
  12.     }    
  13. }      
  14. //....     

面向对象设计两个重要原则:单一职责原则(SRP)和开放-闭合原则(OCP)。SRP要求对每个类仅有一个引起它变化的原因。OCP要求对扩展开放,对修改封闭。<o:p></o:p>

上述代码很容易理解,但它充满臭味:不必要的重复和脆弱性(想象如何把例3展示的CarrierFlight输出到XML)。引起上述代码发生变化的原因很多:Java对象树中某个对象的属性或者XML输出格式改变。同时,缺乏抽象导致该类很难扩展(例如增加对新类型的Object的支持而代码不改变),每次修改都必须改动同一个类。<o:p></o:p>

<o:p>遵循SRP和OCP,需要:</o:p>

<o:p>1.把XML输出和对象解析过程分离</o:p>

<o:p>2.把频繁变化的部分抽象
</o:p>


设计

对象解析

如说封装对象及属性的变化。数值对象有属性组成(以及setter/getter方法,此处忽略);Property(及属性)由类型(已封装成Type类,它将常用的类型定义成类并将静态实例暴露给外界),名称和Alias组成。对象树实际上是数据结构中的树。属性就是叶子。List型属性是可解析的,因此有字节点;非List型属性是末级节点。是否可解析可通过调用listable方法判断。

Property类实现了属性初始化(加载所有属性并生成相应对象供解析时使用)。利用反射机制可获得每个属性的的getter方法并在对象上调用该方法以取得其值。遍历所有节点可构造成一棵Element(稍后还会讲到该接口)树。

XML输出


dom4j是一个开源的XML工具,它支持XML解析和输出。但输出XML的过程采用内存构造Document方式。输出时调用Document.write方法写文件。前面已经提到,由于对象树非常庞大,一次构造完整的Document对象将导致OutOfMemoryError错误。如果能够实现以Append操作XML文件方式替换前面提到的方式,将会避免该问题出现。

Element接口定义了XML元素这个概念。它支持设置元素名称,文本和IO输出操作。XMLStream实现了Element接口,可以表示一个XMl元素并能输出到指定设备。XMLWriter实现了对Element输出到XML的过程。



  • 大小: 33.7 KB
分享到:
评论
5 楼 youbin_ 2007-05-28  
有没有试试axiom,听起来不错哦!
4 楼 zyl 2007-05-19  
引用

我提到要输出对象可能非常非常大,一次输出到XML可能会报OutOfMemoryError。

能有多大的对象?xstream应该支持大对象。不过xstream也有其局限的地方。
3 楼 CALM 2007-05-18  
如果不考虑对象很大,java.beans.XMLEncoder,java.beans.XMLDecoder直接就可以做
2 楼 zerozone 2007-05-18  
zhangbo297600 写道
你这个,不能实现,在对像中,还有别的对像的情况吧,你只实现了最基础的一层式xml。

还不如用这个包
com.thoughtworks.xstream.XStream.
可以将对像直接xstream.toXML(obj),也可以将xml 还原成对像 xstream.fromXML(xml);

所有操作,一句话搞定


说的没错。一句话可以搞定。

但你没理解我的应用上下文,我提到要输出对象可能非常非常大,一次输出到XML可能会报OutOfMemoryError。

所以才有我的解决方案:就是降低操作的对象级别,多次写文件。以缓解可能的内存压力。项目从一开始就确定要避免一次性输出文件。

至于对象中的各种情况,代码没有考虑太多,但支持扩展能力。

com.thoughtworks.xstream.XStream的方法toXML(obj),能否支持超大对象的输出?
1 楼 zhangbo297600 2007-05-18  
你这个,不能实现,在对像中,还有别的对像的情况吧,你只实现了最基础的一层式xml。

还不如用这个包
com.thoughtworks.xstream.XStream.
可以将对像直接xstream.toXML(obj),也可以将xml 还原成对像 xstream.fromXML(xml);

所有操作,一句话搞定

相关推荐

    webservice之使用jaxb把xml转换Object或把对象转换成xml文件

    在Java世界中,使用JAXB(Java Architecture for XML Binding)库可以方便地实现XML数据与Java对象之间的转换,从而在WebService中轻松处理数据交换。本篇文章将深入探讨如何使用JAXB进行XML到Object以及Object到XML...

    JAXB工具类 xml转为java对象 java对象转为xml

    本教程将详细介绍JAXB如何实现XML到Java对象以及Java对象到XML的转换。 ### JAXB概述 JAXB提供了一种自动化的机制,将XML Schema(XSD)映射到Java类,反之亦然。这允许开发者在Java应用中存储和序列化数据为XML...

    java读取跟输出xml文件

    本教程将介绍如何使用Java读取和输出XML文件,主要涉及两个库:JDOM2和XStream。 首先,我们来了解一下JDOM2。JDOM2是一个针对Java平台的API,专门用来处理XML文档。它提供了方便的方法来创建、修改和读取XML文档。...

    Java 使用Tcpip 发送XML文件

    Java中处理XML文件的库有DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)。DOM一次性加载整个XML文档到内存,适合小规模数据;SAX是事件驱动,逐行解析,适合大文件;而...

    JAVA对象与XML互转

    2. **DOM解析**:解析XML文件得到DOM树,然后遍历树并创建相应的Java对象。这通常需要手动编写解析代码,比较繁琐。 3. **SAX解析**:Simple API for XML(SAX)是一种事件驱动的解析方式,适合处理大型XML文件。当...

    Java中写xml文件

    // 创建File对象,指定输出XML文件的路径 File f = new File("XMLOutput.xml"); // 创建StreamResult对象,传入File对象 StreamResult sr = new StreamResult(f); // 使用TransformerFactory创建Transformer对象 ...

    java 解析xml并打印输出

    本示例着重于如何在Java环境中解析XML文件,并将其内容直接打印到打印机上,无需预览。 在Java中,有多种解析XML的方式,包括DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for ...

    java读写xml文件

    Java语言在处理XML文件时,通常使用两种主要的方法:DOM(Document Object Model)和SAX(Simple API for XML)。在本场景中,我们主要关注DOM方法,因为标题和描述提到了“在内存中构造一个DOM树”。DOM允许我们将...

    java对象生成xml数据

    通过它们,你可以方便地实现对象到XML的序列化,从而在各种系统间交换数据,或者将数据持久化到XML文件中。结合合理的对象设计和注解,JAXB可以极大地简化这个过程,提高开发效率。在提供的`demo`文件中,很可能是...

    java写XML文件和读取XML文件

    在Java编程中,处理XML文件是常见的需求,包括创建XML文件、读取XML文件以及解析XML内容。下面将详细介绍Java如何进行XML文件的操作。 一、Java写XML文件 1. 使用DOM(Document Object Model)API: DOM是W3C推荐...

    XStream实现Object与XML转换解决方案

    标题中的“XStream实现Object与XML转换解决方案”指的是一个Java库——XStream,它提供了一种简单的方法来序列化和反序列化Java对象到XML,反之亦然。这个库广泛用于将程序数据保存到XML文件或者从XML数据恢复对象,...

    用Java实现基于SOAP的XML文档网络传输及远程过程调用(RPC).

    总的来说,用Java实现基于SOAP的XML文档网络传输和RPC涉及到多个技术层面,包括XML解析、网络通信、对象序列化和反序列化等。通过理解这些概念和技术,开发者可以构建高效、可靠且跨平台的Web服务。

    java日期和查询数据库生成XML文件类

    在Java编程中,日期处理和数据操作是两个非常重要的领域,尤其当涉及到数据持久化时,如生成XML文件。XML是一种广泛使用的结构化数据交换格式,适用于存储和传输数据。以下是一些关于“java日期和查询数据库生成XML...

    java对象转换成xml格式

    以下将详细讲解如何在Java中实现对象到XML的转换。 1. **JAXB(Java Architecture for XML Binding)** JAXB是Java SE的一部分,它提供了将Java对象直接转换为XML文档,以及从XML文档反序列化回Java对象的能力。...

    java读取XML文件内容小程序

    在这个特定的“java读取XML文件内容小程序”中,使用的是XAM(可能是指JAXB,Java Architecture for XML Binding)解析器,它是一种基于Java注解的XML绑定技术,可以将XML数据自动映射到Java对象,反之亦然。...

    自己写的java对xml文件操作的类

    针对XML文件的操作,Java提供了多种API,如DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)。本项目中,你创建了一个自定义的Java类,用于实现XML文件的基本操作,包括...

    如何将java对象转换成xml

    - **DOM(Document Object Model)**:DOM提供了一种树形结构来表示XML文档,允许程序员通过创建节点来构建XML,或者解析XML文档来创建Java对象。 - **SAX(Simple API for XML)**:这是一种事件驱动的解析器,...

    java对xml操作的项目案例

    本项目案例“java对xml操作的项目案例”深入探讨了如何使用Java来读取、修改和写入XML文件。下面将详细阐述相关知识点。 一、Java与XML的交互 1. DOM解析器:Document Object Model (DOM) 是一种将整个XML文档加载...

    XML转java代码工具

    在实际开发中,将XML数据映射到Java对象(通常称为POJO,Plain Old Java Object)是一种常见的需求,这样可以方便地对XML数据进行操作和处理。 "XML转Java代码工具"是一个实用程序,它的主要功能是自动化这个过程,...

    java对象转Xml

    - 使用`JAXBContext`的`createMarshaller()`方法创建`Marshaller`对象,然后调用`marshal()`方法,将Java对象转换为XML字符串或写入XML文件。 4. **DOM (Document Object Model)**: 另一种方法是使用DOM API,它...

Global site tag (gtag.js) - Google Analytics