【问题标题】:Spring Boot batch - reading XML input - convert elements to listSpring Boot批处理-读取XML输入-将元素转换为列表
【发布时间】:2015-10-09 07:20:29
【问题描述】:

我必须使用 Spring Boot 编写一个批处理服务,该服务读取一个 XML 文件作为输入。 XML 输入的结构如下所示,我无法更改:

<root>
    <parent>
        <field1>string</field1>
        <field2>string</field2>
        <field3>string</field2>
        <child>
            <fieldA>string</fieldA>
            <fieldB>string</fieldB>
        </child>
        <child>
            <fieldA>string</fieldA>
            <fieldB>string</fieldB>
        </child>
        <child>
            <fieldA>string</fieldA>
            <fieldB>string</fieldB>
        </child>
    </parent>
</root>

我已经创建了我的 Java 类:

public class Parent {
    private String field1;
    private String field2;
    private String field3;
    private List<Child> children;

    // Getters and setters...
}

public class Child {
    private String fieldA;
    private String fieldB;

    // Getters and setters...
}

这是我在批处理配置类中的读者:

@Bean
public ItemReader<Object> reader(){
    StaxEventItemReader<Object> reader = new StaxEventItemReader<Object>();
    reader.setResource( new ClassPathResource("input.xml") );
    reader.setFragmentRootElementName("parent");

    XStreamMarshaller unmarshaller = new XStreamMarshaller();
    Map<String, Class> aliases = new HashMap<String, Class>();
    aliases.put( "parent", Parent.class );
    aliases.put( "child", Child.class );
    unmarshaller.setAliases(aliases);

    reader.setUnmarshaller( unmarshaller );
    return reader;
}

现在我只是尝试正确阅读。 但是当我运行批处理时,我有一个错误:

org.springframework.oxm.UnmarshallingFailureException: XStream unmarshalling exception; nested exception is com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field foo.bar.Parent.child

我了解这个错误,但我找不到更正我的代码的方法。 我试图在 Parent 中创建一个假的二传手,将孩子添加到孩子列表中。但这似乎不起作用。

有什么想法吗?

【问题讨论】:

    标签: java xml spring spring-boot spring-batch


    【解决方案1】:

    我使用 Jaxb2Marshaller 而不是 XStreamMarshaller 解决了这个问题:

    @Bean
    public ItemReader<Object> reader(){
        StaxEventItemReader<Object> reader = new StaxEventItemReader<Object>();
        reader.setResource( new ClassPathResource("input.xml") );
        reader.setFragmentRootElementName("parent");
    
        Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
        unmarshaller.setClassesToBeBound( Parent.class, Child.class );
    
        reader.setUnmarshaller( unmarshaller );
        return reader;
    }
    

    对于 Java bean:

    @XmlRootElement(name = "parent")
    public class Parent {
        private String field1;
        private String field2;
        private String field3;
        private List<Child> child;
    
        // Getters and setters...
    }
    
    public class Child {
        private String fieldA;
        private String fieldB;
    
        // Getters and setters...
    }
    

    即使使用自动生成的 getter 和 setter 也可以正常工作:我恢复了子元素的列表。

    【讨论】:

      【解决方案2】:

      重命名此属性:

      private List<Child> children;
      

      private List<Child> child;
      

      并重新创建 getter 和 setter 方法。

      【讨论】:

      • getter 方法中应该放什么?如果我返回列表,则批处理尝试在列表上调用 setFieldA(),但失败。
      猜你喜欢
      • 1970-01-01
      • 2011-07-15
      • 2014-10-20
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多