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