Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理大型XML的javaoo设计_Java_Oop - Fatal编程技术网

处理大型XML的javaoo设计

处理大型XML的javaoo设计,java,oop,Java,Oop,我们正在设计一个处理XML消息的系统 处理Java类需要从一个较大的XML中分离出各种属性和值,并将它们作为参数传递给各个处理程序类,以进行各种操作 我们考虑了以下选择: (A) 将整个XML传递给每个处理程序,并让它提取相关的位——但感觉每次传递XML可能效率低下 (B) 将XML转换为一个DTO或一组较小的DTO,并将每个DTO传递给相关的处理程序 (C) 将XML切割成片段,并将其传递给每个处理程序方法 我们对这些都不满意,所以有什么建议吗 示例XML <IdAction>s

我们正在设计一个处理XML消息的系统

处理Java类需要从一个较大的XML中分离出各种属性和值,并将它们作为参数传递给各个处理程序类,以进行各种操作

我们考虑了以下选择:

(A)

将整个XML传递给每个处理程序,并让它提取相关的位——但感觉每次传递XML可能效率低下

(B)

将XML转换为一个DTO或一组较小的DTO,并将每个DTO传递给相关的处理程序

(C)

将XML切割成片段,并将其传递给每个处理程序方法

我们对这些都不满意,所以有什么建议吗

示例XML

 <IdAction>supplied</IdAction>
    <RegId>true</RegId>
    <DeRegId>false</DeRegId>
    <SaveMessage>false</SaveMessage>
    <ServiceName>abcRequest</ServiceName>
    <timeToPerform>3600</timeToPerform>
    <timeToReceipt/>
    <SendToBES>true</SendToBES>
    <BESQueueName>com.abc.gateway.JMSQueue.forAddRequest</BESQueueName>
    <BESTransform/>
    <BESJMSProperties>
        <property>
            <propName>stateCode</propName>
            <propValue>OK</propValue>
        </property>
    <property>
            <propName>stateResponse</propName>
            <propValue>OK</propValue>
        </property>
    </BESJMSProperties>
已提供
真的
假的
假的
背信
3600
真的
com.abc.gateway.JMSQueue.forAddressRequest
州代码
好啊
状态响应
好啊
它包含由4个处理程序处理的4个块

 <IdAction>supplied</IdAction>
    <RegId>true</RegId>
    <DeRegId>false</DeRegId>
已提供
真的
假的
另一个是

<timeToPerform>3600</timeToPerform>
    <timeToReceipt/>
3600
下一个是

<SendToBES>true</SendToBES>
    <BESQueueName>com.abc.gateway.JMSQueue.forAddRequest</BESQueueName>
    <BESTransform/>
    <BESJMSProperties>
        <property>
            <propName>stateCode</propName>
            <propValue>OK</propValue>
        </property>
    <property>
            <propName>stateResponse</propName>
            <propValue>OK</propValue>
        </property>
    </BESJMSProperties>
true
com.abc.gateway.JMSQueue.forAddressRequest
州代码
好啊
状态响应
好啊

等等

B对我来说似乎是最好的选择。A是最低效的,C大概需要一个过程来解析它并找出片段,然后第二个过程来正确处理它们

使用SAX解析出最小的DTO集,以便传输到专用的处理程序类

好问题,顺便说一句。提前考虑这些事情,并获得第二、第三、第四种意见,这很好:-)

尝试过了吗?

我个人会为xml创建一个数据模型,并传递数据模型。看看教程。使用自定义数据模型,您可以只将需要的数据映射到模型中,对于处理程序类,您可以传递子节点或xml数据模型的子集,而不是整个数据模型

如果您有一个具有以下结构的xml

<book>
  <title>XML</title>
  <author>
     <firstname>John</firstname>
     <lastname>Doe</lastname>
  </author>
  <isbn>123541356eas</isbn>
</book>
书中提到作者的地方。
然后您可以将Author对象传递给您的handler方法。

您可以在这个用例中使用StAX。每个
processBlock
操作将作用于XMLStreamReader,使其状态前进,随后的
processBlock
操作可以执行其位:

package forum7011558;

import java.io.FileReader;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        Demo demo = new Demo();

        FileReader xml = new FileReader("src/forum7011558/input.xml");
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);

        demo.processBlock1(xsr);
        demo.processBlock2(xsr);
        demo.processBlock3(xsr);
        demo.processBlock4(xsr);
    }

    private void processBlock1(XMLStreamReader xsr) {
        // PROCESS BLOCK 1
    }

    private void processBlock2(XMLStreamReader xsr) {
        // PROCESS BLOCK 2
    }

    private void processBlock3(XMLStreamReader xsr) {
        // PROCESS BLOCK 3
    }

    private void processBlock4(XMLStreamReader xsr) {
        // PROCESS BLOCK 4
    }

}

我认为您不需要在内存使用或性能方面考虑任何特殊的设计因素,因此我会选择使用最少编码量的解决方案,即使用JAXB封送器将xml解析为DTO,然后使用您的计划B。也许设置比StAX更难,但它可以节省您的编写时间任何XML解析

如果您使用的是Spring,那么为org.springframework.oxm.jaxb.Jaxb2Marshaller设置bean非常容易
(8.5.2)

@Jeremy:我们需要将XML中的多个片段制作成一个DTO对象-这是否容易?您能否提供有关文档结构的更多详细信息?例如,是否有一个公共消息头需要分析以确定适当的处理程序,并且正文是在一个节点下,还是在多个同级节点下?@Blaise Doughan:没有公共消息头,所有消息头的顺序都是相同的,我们只是尝试将处理模块化为不同的处理程序。示例附件这些XML消息有多大?是如此巨大以至于你不想同时将它们作为一个整体保存在内存中?@ilcavero:平均每个8-10KB,但在峰值时间,应用程序必须每秒处理100条消息。总堆容量为2GB,通常填充速度很快。这是stax吗?它显示为JDK1.6,我将在weblogic 10.3上运行,所以我认为它已经涵盖了?@romesub-是的,这个示例使用JavaSE6(JDK1.6)中的STAXAPI。weblogicserver10.3还支持staxapi:请记住,如果您已经拥有xsd,则可以使用JAXB生成javapojo,如果您已经拥有pojo,则可以使用JAXB生成xsd。如果您使用maven,这可以节省一些工作,请查看:(for code->xsd)和(for xsd->code)
package forum7011558;

import java.io.FileReader;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        Demo demo = new Demo();

        FileReader xml = new FileReader("src/forum7011558/input.xml");
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);

        demo.processBlock1(xsr);
        demo.processBlock2(xsr);
        demo.processBlock3(xsr);
        demo.processBlock4(xsr);
    }

    private void processBlock1(XMLStreamReader xsr) {
        // PROCESS BLOCK 1
    }

    private void processBlock2(XMLStreamReader xsr) {
        // PROCESS BLOCK 2
    }

    private void processBlock3(XMLStreamReader xsr) {
        // PROCESS BLOCK 3
    }

    private void processBlock4(XMLStreamReader xsr) {
        // PROCESS BLOCK 4
    }

}