java Spring Boot 批处理 - 读取 XML 输入 - 将元素转换为列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33032280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:06:22  来源:igfitidea点击:

Spring Boot batch - reading XML input - convert elements to list

javaxmlspringspring-bootspring-batch

提问by Eria

I have to code a batch service, using Spring Boot, that reads an XML file as input. The structure of the XML input looks like this, and I can't change it :

我必须使用 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>

I've created my Java classes :

我已经创建了我的 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...
}

And here is my reader in the batch configuration class :

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

@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;
}

For now I just try to have a correct reading. But when I run the batch, I have an error :

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

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

I understand this error, but I can't find a way to correct my code. I tried to create a fake setter in Parent, adding the child to the children list. But it doesn't seem to work.

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

Any idea ?

任何的想法 ?

回答by Eria

I solved the problem using Jaxb2Marshaller instead of XStreamMarshaller :

我使用 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;
}

And for Java beans :

对于 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...
}

This works fine, even with the auto-generated getters and setters : I recover a list of the children elements.

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

回答by Jens

rename this property:

重命名此属性:

private List<Child> children;

to

private List<Child> child;

and recreate the getter and setter methods.

并重新创建 getter 和 setter 方法。