Spring Boot batch - reading XML input - convert elements to list
Solution 1
I solved the problem using Jaxb2Marshaller instead of 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 :
@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.
Solution 2
rename this property:
private List<Child> children;
to
private List<Child> child;
and recreate the getter and setter methods.
Eria
Updated on June 04, 2022Comments
-
Eria almost 2 years
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 :
<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 :
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.
Any idea ?