6.7.1 StaxEventItemReader

StaxEventItemReader 提供了从XML输入流进行记录处理的典型设置。 首先,我们来看一下 StaxEventItemReader能处理的一组XML记录。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <records>
  3. <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain">
  4. <isin>XYZ0001</isin>
  5. <quantity>5</quantity>
  6. <price>11.39</price>
  7. <customer>Customer1</customer>
  8. </trade>
  9. <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain">
  10. <isin>XYZ0002</isin>
  11. <quantity>2</quantity>
  12. <price>72.99</price>
  13. <customer>Customer2c</customer>
  14. </trade>
  15. <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain">
  16. <isin>XYZ0003</isin>
  17. <quantity>9</quantity>
  18. <price>99.99</price>
  19. <customer>Customer3</customer>
  20. </trade>
  21. </records>

能被处理的XML记录需要满足下列条件:

  • Root Element Name 片段根元素的名称就是要映射的对象。上面的示例代表的是 trade 的值。
  • Resource Spring Resource 代表了需要读取的文件。
  • Unmarshaller Spring OXM提供的Unmarshalling 用于将 XML片段映射为对象.

#

  1. <bean id="itemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  2. <property name="fragmentRootElementName" value="trade" />
  3. <property name="resource" value="data/iosample/input/input.xml" />
  4. <property name="unmarshaller" ref="tradeMarshaller" />
  5. </bean>

请注意,在上面的例子中,我们选用一个 XStreamMarshaller, 里面接受一个id为 aliases 的 map, 将首个entry的 key 值作为文档片段的name(即根元素), 将 value 作为绑定的对象类型。类似于FieldSet, 后面的其他元素映射为对象内部的字段名/值对。在配置文件中,我们可以像下面这样使用Spring配置工具来描述所需的alias:

  1. <bean id="tradeMarshaller"
  2. class="org.springframework.oxm.xstream.XStreamMarshaller">
  3. <property name="aliases">
  4. <util:map id="aliases">
  5. <entry key="trade"
  6. value="org.springframework.batch.sample.domain.Trade" />
  7. <entry key="price" value="java.math.BigDecimal" />
  8. <entry key="name" value="java.lang.String" />
  9. </util:map>
  10. </property>
  11. </bean>

当 reader 读取到XML资源的一个新片段时(匹配默认的标签名称)。reader 根据这个片段构建一个独立的XML(或至少看起来是这样),并将 document 传给反序列化器(通常是一个Spring OXM Unmarshaller 的包装类)将XML映射为一个Java对象。

总之,这个过程类似于下面的Java代码,其中配置了 Spring的注入功能:

  1. StaxEventItemReader xmlStaxEventItemReader = new StaxEventItemReader()
  2. Resource resource = new ByteArrayResource(xmlResource.getBytes())
  3. Map aliases = new HashMap();
  4. aliases.put("trade","org.springframework.batch.sample.domain.Trade");
  5. aliases.put("price","java.math.BigDecimal");
  6. aliases.put("customer","java.lang.String");
  7. Marshaller marshaller = new XStreamMarshaller();
  8. marshaller.setAliases(aliases);
  9. xmlStaxEventItemReader.setUnmarshaller(marshaller);
  10. xmlStaxEventItemReader.setResource(resource);
  11. xmlStaxEventItemReader.setFragmentRootElementName("trade");
  12. xmlStaxEventItemReader.open(new ExecutionContext());
  13. boolean hasNext = true
  14. CustomerCredit credit = null;
  15. while (hasNext) {
  16. credit = xmlStaxEventItemReader.read();
  17. if (credit == null) {
  18. hasNext = false;
  19. }
  20. else {
  21. System.out.println(credit);
  22. }
  23. }