Javax.xml.bind.Marshaller.Listener.afterMarshal() Method



Description

The Javax.xml.bind.Marshaller.Listener.afterMarshal(Object source) callback method invoked after marshalling from source to XML.

This method is invoked after source and all its descendants have been marshalled. Note that if the class of source defines its own afterMarshal method, the class specific callback method is invoked just before this method is invoked.

Declaration

Following is the declaration for javax.xml.bind.Marshaller.Listener.afterMarshal(Object source) method

public void afterMarshal(Object source)

Parameters

source − instance of JAXB mapped class after marshalling it.

Return Value

This method does not return any value.

Exception

NA

Example

The following example shows the usage of javax.xml.bind.Marshaller.Listener.beforeMarshal(Object source) method. To proceed, consider the following Root class which will be used to have objects for marshalling purpose −

package com.tutorialspoint;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlJavaTypeAdapter(XMLRootAdapter.class)
@XmlType(propOrder={"name", "child"})
public class Root {

   private String name;
   private Root child;

   public Root getChild() {
      return child;
   }

   public void setChild(Root report) {
      this.child = report;
   }
    
   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

Now let us create main class which will be used to marshal ie. convert Root object into an XML file. This example marshals the Root object and prints it at STDOUT, but in practical scenario you can store the object in any file as an XML node.

package com.tutorialspoint;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class MarshallerListenerDemo {
   public static void main(String[] args) throws Exception {
      
      try {
         // create JAXBContext
         JAXBContext jc = JAXBContext.newInstance(Root.class);
         
         // create new root
         Root rootA = new Root();
         rootA.setName("1");
         
         Root rootB = new Root();
         rootB.setName("2");
         rootA.setChild(rootB);
         
         Root rootC = new Root();
         rootC.setName("3");
         rootB.setChild(rootC);
         
         Root rootD = new Root();
         rootD.setName("4");
         rootC.setChild(rootD);
         
         Root rootE = new Root();
         rootE.setName("5");
         rootD.setChild(rootE);
         
         // create marshaller
         Marshaller marshaller = jc.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
         
         // create new depth listener at depth 4
         DepthListener depthListener = new DepthListener(4);
         marshaller.setListener(depthListener);
         marshaller.setAdapter(new XMLRootAdapter(depthListener));
         marshaller.marshal(rootA, System.out);   
      } catch(Exception e) {
         e.printStackTrace();
      }
   }
}

We will use DepthListener class to keep track of the current depth before and after marshal. The DepthListener class is as follows −

package com.tutorialspoint;

import javax.xml.bind.Marshaller;

public class DepthListener extends Marshaller.Listener {

   private int targetDepth;
   private int depth = 0;

   public DepthListener(int depth) {
      this.targetDepth = depth;
   }

   @Override
   public void beforeMarshal(Object source) {
      depth++;
   }

   @Override
   public void afterMarshal(Object source) {
      depth--;
   }

   public boolean isMarshalDepth() {
      return depth <= targetDepth; 
   }
}

We will add another XmlAdapter class to start returning null when the desired depth has been reached.

package com.tutorialspoint;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class XMLRootAdapter extends XmlAdapter<Root, Root> {

   private DepthListener depthListener;

   Public XMLRootAdapter() {
   }

   public XMLRootAdapter(DepthListener depthListener) {
      this.depthListener = depthListener;
   }

   @Override
   public Root unmarshal(Root root) throws Exception {
      return root;
   }

   @Override
   public Root marshal(Root root) throws Exception {
      if(depthListener != null && !depthListener.isMarshalDepth()) {
         return null;
      }
      return root;
   }
}

Before we proceed for compilation, we need to make sure that that we download JAXB2.xxx.jar and put it in our CLASSPATH. Once setup is ready, let us compile and run the above program, this will produce the following result −

<?xml version = "1.0" encoding = "UTF-8" standalone = "yes"?>
<root>
   <name>1</name>
   <child>
      <name>2</name>
      <child>
         <name>3</name>
         <child>
            <name>4</name>
         </child>
      </child>
   </child>
</root>
Advertisements