java - 如何在 Spring Batch ItemWriter 中为子 bean 编写多个 XML 文件?

标签 java xml spring spring-batch itemwriter

我有一个批处理作业,它从数据库中检索记录,处理它们,然后将结果传递给编写器。传递给编写器的 bean 有四个字段需要写入单独的 xml 文件。其中一个字段是代表原始记录的 bean,其他三个字段是与该记录关联的子元素的集合。

我最初尝试使用 jackson 来解析 Bean 并生成文件,但我发现该方法在应用于批处理模型时遇到了麻烦。

接下来,我转而对每个子字段使用 StaxEventItemWriter,这些字段单独看来完全足够,但我在实现可以处理所有各种子类型的编写器时遇到了困难。我研究了 CompositeItemWriterClassifierCompositeItemWriter,但它们似乎更适合为同一类型的 bean 提供多个编写器,而我需要适合不同类型的多个编写器。任何建议将不胜感激!

域示例:

public class MyBean {
    private RecordBean recordBean;
    private List<ChildTypeA> aBeans;
    private List<ChildTypeB> bBeans;
    private List<ChildTypeC> cBeans;
}

@XmlRootElement(name = "RECORD")
public class RecordBean extends MyAbstractBean {
    @XmlElement(name = "ID")
    private String recordId;

    @XmlElementWrapper(name = "A_CHILDREN")
    @XmlElement(name="CHILD_TYPE_A")
    List<Long> aChildIds}

    @XmlElementWrapper(name = "B_CHILDREN")
    @XmlElement(name="CHILD_TYPE_B")
    List<Long> bChildIds}

    @XmlElementWrapper(name = "C_CHILDREN")
    @XmlElement(name="CHILD_TYPE_C")
    List<Long> cChildIds}
}

@XmlRootElement(name = "CHILD_TYPE_A")
public class ChildTypeA extends MyAbstractBean {
    @XmlElement(name = "ID") private String aId;
}

@XmlRootElement(name = "CHILD_TYPE_B")
public class ChildTypeB extends MyAbstractBean {
    @XmlElement(name = "ID") private String bId;
}

@XmlRootElement(name = "CHILD_TYPE_C")
public class ChildTypeC extends MyAbstractBean {
    @XmlElement(name = "ID") private String cId;
}

对于传递给编写器的每个容器 bean,我需要为每个 RecordBean 创建一个唯一的 XML 文件,例如record_1.xml,我需要将每个集合写入一个聚合文件,该文件将用作该子类型的所有子项的库,涵盖所有记录。

输出示例: record_1.xml

<?xml version="1.0" encoding="UTF-8"?>
<RECORD>
    <ID>1</ID>
    <A_CHILDREN>
        <CHILD_TYPE_A>1</CHILD_TYPE_A>
        <CHILD_TYPE_A>2</CHILD_TYPE_A>
    </A_CHILDREN>
    <B_CHILDREN>
        <CHILD_TYPE_B>1</CHILD_TYPE_B>
        <CHILD_TYPE_B>2</CHILD_TYPE_B>
    </B_CHILDREN>
    <A_CHILDREN>
        <CHILD_TYPE_C>1</CHILD_TYPE_C>
        <CHILD_TYPE_C>2</CHILD_TYPE_C>
    </A_CHILDREN>
</RECORD>
</xml>

record_2.xml

<?xml version="1.0" encoding="UTF-8"?>
<RECORD>
    <ID>2</ID>
    <A_CHILDREN>
        <CHILD_TYPE_A>3</CHILD_TYPE_A>
        <CHILD_TYPE_A>4</CHILD_TYPE_A>
    </A_CHILDREN>
    <B_CHILDREN>
        <CHILD_TYPE_B>3</CHILD_TYPE_B>
        <CHILD_TYPE_B>4</CHILD_TYPE_B>
    </B_CHILDREN>
    <A_CHILDREN>
        <CHILD_TYPE_C>3</CHILD_TYPE_C>
        <CHILD_TYPE_C>4</CHILD_TYPE_C>
    </A_CHILDREN>
</RECORD>
</xml>

a_children.xml

<?xml version="1.0" encoding="UTF-8"?>
<A_CHILDREN>
    <CHILD_TYPE_A>
        <ID>1</ID>
    </CHILD_TYPE_A>
    <CHILD_TYPE_A>
        <ID>2</ID>
    </CHILD_TYPE_A>
    <CHILD_TYPE_A>
        <ID>3</ID>
    </CHILD_TYPE_A>
    <CHILD_TYPE_A>
        <ID>4</ID>
    </CHILD_TYPE_A>
</A_CHILDREN>
</xml>
<!-- Decide which format to use -->

b_children.xml 和 c_children.xml 与 a_children.xml 相同。

最佳答案

因此,经过两天的大部分时间,我决定采取不同的方法。我认为可以创建一组编写器来处理该任务,但我认为这需要大量的定制和复杂的委托(delegate)层次结构。

例如:

  • CompositeItemWriter 委托(delegate)给:
    • ClassifierCompositeItemWriter 进行分类并委托(delegate)给:
      • ChildTypeA 的 StaxEventItemWriter
      • StaxEventItemWriter(适用于 ChildTypeB)
      • StaxEventItemWriter 用于 ChildTypeC
    • MultiResourceItemWriter 为每个 RecordBean 动态分配 FilesystemResource。

尽管事实上这可能是可行的,但我意识到将 XML 写为字符串在任何我想要的地方会更简单。大致如下:

@Component
@Scope("step")
public class MyXmlWriter implements ItemWriter<MyBean> {
    @Override
    public void write(List<? extends MyBean> beans) throws Exception {
        for(MyBean bean : beans) {
            this.writeRecordBean(bean.getRecordBean());
            bean.getAChildIds().forEach(a -> this.writeElement(a, pathA));
            bean.getBChildIds().forEach(b -> this.writeElement(b, pathB));
            bean.getCChildIds().forEach(c -> this.writeElement(c, pathC));
        }
    }

    private void writeElement(Long Id, Path path) {
        // Handle serialization and FileIO here
    }

    .
    .
    .

}

无论如何,我希望这可以帮助任何像我一样深入研究 Spring Batch 杂草的人。干杯!

关于java - 如何在 Spring Batch ItemWriter 中为子 bean 编写多个 XML 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58545822/

相关文章:

Java xPath - 从 XML 中提取子文档

Spring Caching - 忽略键的参数

java - 使用静态页面在 spring mvc 部署中苦苦挣扎

java - 如何使用命令行参数打印ms Office文件?

java - 如何使用 GridLayout 从 JFrame 获取组件?

java - 我可以在我的独立应用程序中使用谷歌翻译API吗

Java 属性 - 全局和局部属性

php - cURL 添加空格以发布内容?

php - 如何从谷歌地图 API 检索数据

Spring OAuth2 不会在表单登录时重定向回客户端