【问题标题】:How to access/read objects inside Itemreader/StaxEventItemReader correctly?如何正确访问/读取 Itemreader/StaxEventItemReader 中的对象?
【发布时间】:2021-10-22 00:56:03
【问题描述】:

我是 Spring Batch 的新手,我有一个应用程序,例如,可以读取航班的 xml 文件并将其保存到数据库中。整个过程已经开始工作,但由于某个用例,如果可能的话,我还需要访问 reader 对象 (ItemReader) 中的数据。 下面是阅读器方法。这不是特别关于这种方法,而是如前所述,它是关于 ItemReader。

@Bean
public StaxEventItemReader<Flight> flightReader() {

    StaxEventItemReader<Flight> reader = new StaxEventItemReader<Obj>();
    reader.setResource(ressource);
    reader.setFragmentRootElementName("flight");

    Map<String, String> aliases = new HashMap<String, String>();
    aliases.put("flight", Flight.class);

    XStreamMarshaller xStreamMarshaller = new XStreamMarshaller();
    xStreamMarshaller.setAliases(aliases);

    reader.setUnmarshaller(xStreamMarshaller);
    
    return reader;
}

如何访问阅读器 (StaxEventItemReader) 对象中的飞行对象?

我实际上尝试使用 read() 方法 (Spring doc ItemReader),但我总是收到 NullPointerExceptions。

如果 read() 方法是正确的,如何才能正确访问 ItemReader 中的飞行对象? 如果没有,还有其他方法吗?

【问题讨论】:

  • 阅读器在读取数据前必须先打开(看它如何实现ItemStream)。当在面向块的步骤中使用此阅读器时,Spring Batch 会自动调用 open/update/close 方法,但如果您在步骤之外使用它(例如在单元测试中),则由您来调用这些方法来兑现ItemSteam 合同。在您的情况下,这可能是导致 NPE 的原因。除此之外,第二个是 Henning 的答案。

标签: spring spring-boot spring-batch


【解决方案1】:

访问项目的方法不止一种。这真的取决于你想用它们做什么:

  • 如果您只想查看而不操作项目,您可以使用其afterRead 方法实现ItemReadListener,并将侦听器添加到您的步骤中。
  • 项目被传递给处理器。所以你可以在那里对它们进行操作。
  • 您可以扩展类 StaxEventItemReader 并覆盖 read 方法以包含其他逻辑。
  • 如果您更喜欢组合而不是继承,您可以编写一个使用StaxEventItemReader 作为委托的新阅读器。

【讨论】:

  • 为了澄清:实际上我猜这是一个相当不寻常的用例。对于测试,我需要在开始测试之前将飞行数据保存到测试数据库。由于阅读器方法已经存在,因此建议我应该只使用 Itemreader 并遍历项目,以便我可以将它们保存到数据库中。但目前问题仍然存在,即 read() 方法不起作用(空指针)。您对这个特定用例应该做什么或如何正确使用 read() 方法有什么建议吗?
  • 阅读器是有状态的。一旦它读取了所有项目,它的read() 方法将始终返回null。如果您想使用阅读器两次,则需要创建阅读器的两个实例。
  • 如果您将 reader 作为 bean 同时注入到作业和测试中,则它与 bean 是单例的实例相同。
猜你喜欢
  • 2021-10-25
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 2020-02-26
  • 2012-11-25
相关资源
最近更新 更多