1
votes

I am currently writing spring batch where i am reading a XML data , processing it and then pass the processor result as map<string,object> to writer and implemented CompositeItemWriter. Following is the required output XML.

 <Company att1="value">
      <employees>
        <employee></employee>
         <employee></employee>
         <employee></employee>
      <employees>
    </Company>

Generated JAXB xjc classes for marshalling and unmarshalling. JAXB generated class looks like the below.

@XmlRootElement(name="Company")
public class Company{
@XmlElements(name="employees" required="true")
}

JAXB Employee class

@XmlRootElement(name="employees")
public class Employees
{
@XmlElement(name="Employee")
protected List<Employees> employee;
}

Spring XML configuration file

<batch:job id="reportJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="xmlItemReader" 
 writer="compositeItemWriter" processor="filterReportProcessor"
 commit-interval="2">
 </batch:chunk>
 </batch:tasklet>
</batch:step>
</batch:job>



<!-- Filtering process -->
<bean id="filterReportProcessor" class="com.examples.FilterReportProcessor" />

<bean id="xmlItemReader" 
    class="org.springframework.batch.item.xml.StaxEventItemReader">
<property name="fragmentRootElementName" value="record" />
<property name="resource" value="classpath:xml/company.xml" />
<property name="unmarshaller" ref="reportUnmarshaller" />
</bean>

<!-- Read and map values to object, via jaxb2 -->
<bean id="reportUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
    <value>com.examples.Company</value>
    <value>com.examples.Employees</value>
    <value>com.examples.Employee</value>
</list>
</property>
</bean>

<bean id="compositeItemWriter" class="org.springframework.batch.item.support.CompositeItemWriter">
<property name="delegates"/>
    <list>
       <ref bean="testXMlWriter">
  </list>
</bean>
<bean id="testXMlWriter" class="com.test.example.TestXMLWriter">

Processor and Writer :

    public class FilterReportProcessor
    implement ItemProcessor<Employee,Map<String,Object>>{
    public Map<String,Object> process(Employee emplpyee) throws Exception{
    Map<String,Object> evnt = Mapper.crateMapping(emplpyee);
    return event; 
    }

    public class TestXMLWriter implemtes ItemWriter(Map<String,Object>){
    write(List <? extends Map<String, object>> lst){

    Employee e1 = new Employee();
    e1.setxxx(mapelementdata.item());

    Employees employs = new Employees();
    employs.add(e1);
    Comapany c1 = new Company();
    c1.add(employs);

   Marshaller m = context.createMarshaller();
   m.marshal(c1, resource.getFile());
  }

Question :

XML file is overriding for each fixed commit-intervals, It is obvious that XML file creates after each commit-level. But i have to append all the <employee> objects to same XML file. how to implement this logic to append the <employee> objects after every commit interval ?

1
what is the question?Pooya
how to append new xml records in same batch step excecution.vanreddy
Modified question and repostedvanreddy

1 Answers

0
votes

I think you want to write to the same file , in that case i would recommend using FlatFileItemWriter instead of the custom writer you have and set the property appendAllowed to true , this would append to the file if it already exists.Move the processing logic to your processor and using lineAggregator to batch a number of lines together for a write.

If you do not want to do that then you have to resort to a little more complex coding , of opening the file in the beforeWrite method of a WriterListener, reading the content and then storing it in the context and then pushing it to the write method.