使用 split、stax、jaxb 使用 Apache Camel 拆分大型 XML 文件
Splitting a large XML file with Apache Camel using split, stax, jaxb
我在 sftp 服务器上有一个很大的 XML 文件(可能有大约百万条记录)。我不想将整个文件加载到内存中。目的是我的路线获取文件,拆分它并使用 stax 构建器迭代元素并将其映射到 JAXB 对象并将其发送到队列(或 spring 批处理)以便稍后保留到数据库。
input.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>
骆驼路线
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();
PartRecord.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;
}
PartRecords.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 中的整个文件被放入队列。我想这是正常行为,所以我需要一些额外的东西。我不知道每条记录有 1 条消息是否是个好主意,但我想有 1 条消息包含整个文件也不是高效的。
当前行为输出
{
"partRecords" : [ {
"productNumber" : "8D0201075E",
"currentPrice" : 427.90,
"partDescriptionNL" : "Some description",
"partDescriptionFR" : "Some description"
}, {
"productNumber" : "99630211802",
"currentPrice" : 3.78,
"partDescriptionNL" : null,
"partDescriptionFR" : "Some description"
}]
}
我做错了什么?我正在使用 Spring Boot v2.5.4,Apache Camel v3.11.1。提前致谢。
在路由器中使用 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();
我在 sftp 服务器上有一个很大的 XML 文件(可能有大约百万条记录)。我不想将整个文件加载到内存中。目的是我的路线获取文件,拆分它并使用 stax 构建器迭代元素并将其映射到 JAXB 对象并将其发送到队列(或 spring 批处理)以便稍后保留到数据库。
input.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>
骆驼路线
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();
PartRecord.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;
}
PartRecords.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 中的整个文件被放入队列。我想这是正常行为,所以我需要一些额外的东西。我不知道每条记录有 1 条消息是否是个好主意,但我想有 1 条消息包含整个文件也不是高效的。
当前行为输出
{
"partRecords" : [ {
"productNumber" : "8D0201075E",
"currentPrice" : 427.90,
"partDescriptionNL" : "Some description",
"partDescriptionFR" : "Some description"
}, {
"productNumber" : "99630211802",
"currentPrice" : 3.78,
"partDescriptionNL" : null,
"partDescriptionFR" : "Some description"
}]
}
我做错了什么?我正在使用 Spring Boot v2.5.4,Apache Camel v3.11.1。提前致谢。
在路由器中使用 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();