Search code examples
javaxmljaxbmarshalling

How to determine that JAXB is done marshalling to file


On a server there is a process that picks up files from a specific directory every specific interval (say 5 minutes). The files that are being pickup is are generated by a webservice. JAXB marshalling converts the files from objects to xml files. The issue is it occurs frequently that files are being picked up before they are done. A solution is to place the files in a temp directory or give them a temporary specific extension to let the polling process know to skip these. Afterwards the files can be moved to the processing directory or extension can be changed so that the polling process can pick them up.

The method looks like this;

    private void writeToFile(Object obj, String outputFileName) {
    LOG.debug("Executing operation writeToFile using filename '{}' and object of type '{}'.", outputFileName, obj.getClass());

    try {
        Marshaller jaxbMarshaller = JAXB_CONTEXT.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.marshal(obj, new File(outputFileName));
        LOG.debug("Wrote request to file '{}'.", outputFileName);
    } catch (JAXBException e) {
        LOG.error("Exception occurred while writing request to file:", e);
    }
    LOG.debug("Done executing operation writeToFile.");
}

My question is hot to dtermine that the marshalling proces is done so that the file can be released for further processing?


Solution

  • Please download the code from this link [https://turreta.com/2017/03/07/jaxb-perform-pre-and-post-processing-with-unmarshaller-listener/] Add the below Person Marshall Listener code to the source, as this will be called for each node have checked the root Node instance inside of Person (this needs to be modified as your base node) in both before and After Marshall Methods, also used a count of 2 because the start and end node calls this each time, as this should be called only on end node check if count == 2

    package com.turreta.jaxb.unmarshaller.listener;
    
        public class PersonMarshallListener extends javax.xml.bind.Marshaller.Listener {
    
                int beforeCount = 1;
                int afterCount = 1;
    
              @Override
               public void beforeMarshal(Object source) {
                  super.beforeMarshal(source);
                  if (source instanceof Person) {
    
                      if (beforeCount == 2) {
                          beforeCount = 1;
                          System.out.println("BEFORE MARSHAL");
                      } else {
                          beforeCount++;
                      }
                  }
    
               }
    
               @Override
               public void afterMarshal(Object source) {
                   super.afterMarshal(source);
    
                   if (source instanceof Person) {
    
                       if (afterCount == 2) {
    
                           afterCount = 1;
                           System.out.println("AFTER MARSHAL");
        //                 System.out.println("This will be called once the marshall has been completed");
                       } else {
                           afterCount++;
                       }
                   }
    
    
               }
    
        }
    

    And replace the DemoApp with the following code

    package com.turreta.jaxb.unmarshaller.listener;
    
    import java.io.FileInputStream;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamReader;
    
    public class DemoApp {
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Person.class);
    
            XMLInputFactory xif = XMLInputFactory.newFactory();
            FileInputStream xml = new FileInputStream("src/main/resources/person.xml");
            XMLStreamReader xsr = xif.createXMLStreamReader(xml);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            PersonUnmarshallListener pul = new PersonUnmarshallListener();
            unmarshaller.setListener(pul);
    
            Person person = (Person) unmarshaller.unmarshal(xsr);
            System.out.println(person);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setListener(new PersonMarshallListener());
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(person, System.out);
    
    
        }
    }