Somebody
Somebody

Reputation: 2779

Unable to unmarshal xml elements into string - Spring Batch

I have below sample XML that I need to read each contact element as String for later in the processor using dom4j for a simpler processing, the actual XML is way more complex than the one below, this is just for reproducing the issue I'm having:

<query>
    <contact>
        <full_name>
            <first_name>John</first_name>
            <last_name>Doe</last_name>
        </full_name>
        <street>111 Main St</street>
        <city>Chicago</city>
        <state>IL</state>
        <zip>60610</zip>
    </contact>
    <contact>
        <full_name>
            <first_name>Jane</first_name>
            <last_name>Smith</last_name>
        </full_name>
        <street>222 Main St</street>
        <city>Miami</city>
        <state>FL</state>
    </contact>
</query>

BatchConfiguration.java

@Configuration
@EnableBatchProcessing
@Slf4j
public class BatchConfiguration {
    
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    
    @Autowired
    public ContactItemProcessor contactItemProcessor;
    
    @Bean
    public StaxEventItemReader<String> reader() {
        
        StaxEventItemReader<String> reader = new StaxEventItemReader<>();
        
        try {
            Map<String, Class<?>> aliases = new HashMap<>();
            aliases.put("contact", String.class);
            
            XStreamMarshaller unmarshaller = new XStreamMarshaller();
            unmarshaller.setAliases(aliases);           
            
            reader.setName("itemReader");
            reader.setResource(new FileSystemResource("contact-list.xml"));
            reader.setFragmentRootElementName("contact");
            reader.setUnmarshaller(unmarshaller);
        } catch (Exception e) {
            log.error("ERROR in StaxEventItemReader :: Error while reading: {}", e.getMessage());
        }
        
        return reader;
    }
    
    @Bean
    public FlatFileItemWriter<Contact> writer() {
        
        FlatFileItemWriter<Contact> writer = new FlatFileItemWriter<>();
        writer.setResource(new FileSystemResource("contact-out.dat"));
        writer.setLineAggregator(new DelimitedLineAggregator<Contact>() {
            {
                setDelimiter(",");
                setFieldExtractor(new BeanWrapperFieldExtractor<Contact>() {
                    {
                        setNames(new String[] { "firstName", "lastName", "street", "city", "state", "zip" });
                    }                   
                });
            }
        });
        
        return writer;
    }
        
    @Bean("InputJob")
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Job importUserJob(Step step) {
        return jobBuilderFactory.get("importUserJob")
          .incrementer(new RunIdIncrementer())          
          .flow(step)
          .end()
          .build();
    }

    @Bean
    public Step step(FlatFileItemWriter<Contact> writer) {      
        return stepBuilderFactory.get("step")
          .<String, Contact> chunk(10)
          .reader(reader())          
          .processor(contactItemProcessor)
          .writer(writer)          
          .build();
    }

}

ContactItemProcessor.java

@Component
public class ContactItemProcessor implements ItemProcessor<String, Contact> {

    @Override
    public Contact process(String item) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}

In above ContactItemProcessor class the item string value that is coming from the reader is: \n\t\t, is not bringing the actual contact element, not sure why.

Upvotes: 0

Views: 224

Answers (1)

Mar-Z
Mar-Z

Reputation: 4778

If you want to unmarshal to Contact class you should define the alias as follows:

aliases.put("contact", Contact.class);

Upvotes: 0

Related Questions