使用split、stax、jaxb和Apache Camel拆分大型XML文件

dphi5xsq  于 2022-11-07  发布在  Apache
关注(0)|答案(1)|浏览(175)

我在sftp服务器上有一个很大的XML文件(可能有上百万条记录)。我不想把整个文件加载到内存中。我的目的是让我的路由选择这个文件,将其拆分,然后使用stax构建器迭代元素,将其Map到JAXB对象,并将其发送到队列(或spring batch),以便以后持久化到数据库中。

输入.xml(仅2条记录作为示例)

<data>
    <PRODUCTNUMBER>
        <PRODUCTNUMBER>8D0201075E</PRODUCTNUMBER>
        <CURRGROSSPRICE>427.90</CURRGROSSPRICE>
        <NEXTGROSSPRICE>0.00</NEXTGROSSPRICE>
        <NEXTPRICEDATE>1900-01-01 00:00:00</NEXTPRICEDATE>
        <PRODUCTNAME_FR>Some description</PRODUCTNAME_FR>
        <PRODUCTNAME_NL>Some description</PRODUCTNAME_NL>
    </PRODUCTNUMBER>

    <PRODUCTNUMBER>
        <PRODUCTNUMBER>99630211802</PRODUCTNUMBER>
        <CURRGROSSPRICE>3.78</CURRGROSSPRICE>
        <NEXTGROSSPRICE>0.00</NEXTGROSSPRICE>
        <NEXTPRICEDATE>1900-01-01 00:00:00</NEXTPRICEDATE>
        <PRODUCTNAME_FR>Some description</PRODUCTNAME_FR>
    </PRODUCTNUMBER>
</data>

" Camel 路线"

from("sftp:localhost:22/in")
   .split(stax(PartRecords.class)).streaming()
   .marshal().json(JsonLibrary.Jackson, true)
   .to("rabbitmq://rabbitmq:5672/myExchange?queue=partQueue&routingKey=queue.part")
   .end();

部分记录.java

@XmlRootElement(name = "PRODUCTNUMBER")
@XmlAccessorType(XmlAccessType.FIELD)
@Getter
@Setter
@ToString
public class PartRecord implements Serializable {

    @XmlElement(name = "PRODUCTNUMBER")
    private String productNumber;

    @XmlElement(name = "CURRGROSSPRICE")
    private BigDecimal currentPrice;

    @XmlElement(name = "PRODUCTNAME_NL")
    private String partDescriptionNL;

    @XmlElement(name = "PRODUCTNAME_FR")
    private String partDescriptionFR;

}

零件记录.java

@XmlRootElement(name = "data")
@XmlAccessorType(XmlAccessType.FIELD)
@ToString
public class PartRecords implements Serializable {

    @XmlElement(name = "PRODUCTNUMBER")
    private List<PartRecord> partRecords;

    public List<PartRecord> getPartRecords() {
        if (partRecords == null) {
            partRecords = new ArrayList<>();
        }
        return partRecords;
    }

}

路由工作正常,一条消息被放到队列中,但是不是每条记录一条消息,而是整个json文件被放到队列中。我想这是正常的行为,所以我需要一些额外的东西。我不知道每条记录一条消息是否是个好主意,但我想让一条消息包含整个文件也是不好的。

当前行为输出

{
  "partRecords" : [ {
    "productNumber" : "8D0201075E",
    "currentPrice" : 427.90,
    "partDescriptionNL" : "Some description",
    "partDescriptionFR" : "Some description"
  }, {
    "productNumber" : "99630211802",
    "currentPrice" : 3.78,
    "partDescriptionNL" : null,
    "partDescriptionFR" : "Some description"
  }]
}

我做错了什么?我用的是Sping Boot v2.5.4,Apache Camel v3.11.1。提前感谢。

yruzcnhs

yruzcnhs1#

在路由器中使用 PartRecord 而不是 PartRecords

from("sftp:localhost:22/in")
   .split(stax(PartRecord.class)).streaming()
   .marshal().json(JsonLibrary.Jackson, true)
   .to("rabbitmq://rabbitmq:5672/myExchange?queue=partQueue&routingKey=queue.part")
   .end();

相关问题