首页 > 解决方案 > Spring Batch - StaxEventItemReader 处理 xml 中的无效行

问题描述

我正在使用 Spring Batch 来读取 XML 文件。我想使用 XSD 验证记录。我可以使用运行验证,setSchema但它会抛出异常并杀死整个工作。我的目标是处理这些无效记录,将它们保存到日志中并跳过它们以进行最终处理。

我的 StaxEcentItemReader

    @Bean
    @JobScope
    public StaxEventItemReader<?> reader() throws Exception {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setClassesToBeBound(BookDto.class);
        jaxb2Marshaller.setSchema(new ClassPathResource("book.xsd"));
        jaxb2Marshaller.afterPropertiesSet();

        return new StaxEventItemReaderBuilder<>()
                .name("xmlReader")
                .resource(new ClassPathResource("books.xml"))
                .addFragmentRootElements("book")
                .unmarshaller(jaxb2Marshaller)
                .build();
    }

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.test.com/xsd"
  xmlns="http://www.test.com/xsd"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="book" type="bookDto"/>
  <xs:simpleType name="simAuthor">
    <xs:restriction base="xs:string">
      <xs:maxLength value="10"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="bookDto">
    <xs:sequence>
      <xs:element name="author" type="simAuthor" minOccurs="0"/>
      <xs:element type="xs:float" name="price"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="id" use="required"/>
  </xs:complexType>
</xs:schema>

项目

<?xml version="1.0"?>
<catalog>
  <book xmlns="http://www.test.com/xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com/xsd" id="bk101">
    <author>Gambardella, MatthewMatthewMatthewMatthewMatthewMatthewMatthewMatthew</author>
    <price>44.95s</price>
  </book>
  <book xmlns="http://www.test.com/xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com/xsd" id="bk102">
    <author>Ralls, Kim</author>
    <price>5.95</price>
  </book>
</catalog>

标签: javaspringspring-batch

解决方案


我可以使用 setSchema 运行验证,但它会抛出异常并杀死整个工作。

您可以使用容错步骤并将异常声明为可跳过。有了这个,无效的项目将被跳过,作业将继续下一个项目,而不是在第一个无效项目上失败。有关更多详细信息,请参阅参考文档的配置跳过逻辑部分。

我的目标是处理这些无效记录,将它们保存到日志中并跳过它们以进行最终处理。

为此,您需要注册一个SkipListener并在需要时记录无效项目。


推荐阅读