OXM with Castor.

OXM with Castor.

 

In article I’ll show you fews step to kick start the marshalling and unmarshalling with castor.

Overview

  • Dependencies
  • Sample data
  • Create java object
  • Oxm mapping file
  • Marshalling/Unmashalling Service class
  • ApplicationContext

Dependencies

  • spring-oxm
  • spring-context-support
  • castorxml
  • castor
  • xercesImpl

Sample Data:

Let’s look at the sample data so that we can have some idea how to prepare the classes.

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<ResponseParameter>
  <ResponseHeader>
    <ORD_NO>ABC139-176</ORD_NO>
    <TOTAL_AMOUNT>10000</TOTAL_AMOUNT>
    <SUCCESS_AMOUNT>10000</SUCCESS_AMOUNT>
    <ERROR_CODE>0000</ERROR_CODE>
    <ERROR_MSG>SUCCESS</ERROR_MSG>  
    <SIGNVALUE>23h83jwq8</SIGNVALUE>
  </ResponseHeader>
  <ResponseBody>
    <ResponseItem>
      <SEQ_NO>123456789</SEQ_NO>
      <STATUS>1</STATUS>
      <AMOUNT>10000</AMOUNT>
      <ERROR_CODE>0000</ERROR_CODE>
      <ERROR_MSG>SUCCESS</ERROR_MSG>
      <ORDER_ID>ABC139-176</ORDER_ID>
      <SUCCESS_TIME>20150301153205</SUCCESS_TIME>
    </ResponseItem>
  </ResponseBody>
</ResponseParameter>

Create Java Object

Base on the sample data, I decided split into 4 classes.

  • ResponseParameter
  • ResponseHeader
  • ResponseBody
  • ResponseItem

ResponseParameter

package com.codeomitted.oxm.response;

public class ResponseParameter {

  private ResponseHeader header;
	
  private ResponseBody   body;

  public ResponseHeader getHeader() {
    return header;
  }

  // getter and setter
}

ResponseHeader

package com.codeomitted.oxm.response;

public class ResponseHeader {

  private String ORD_NO;
	
  private String TOTAL_AMOUNT;
	
  private String SUCCESS_AMOUNT;
	
  private String ERROR_CODE;
	
  private String ERROR_MSG;
	
  private String SIGNVALUE;

  // getter and setter

}

ResponseBody

package com.codeomitted.oxm.response;

public class ResponseBody {

  private ResponseItem item;

  public Item getResponseItem() {
    return item;
  }

  public void setResponseItem(ResponseItem item) {
    this.item = item;
  }
}

ResponseItem

package com.codeomitted.oxm.response;

public class ResponseItem {

  private String SEQ_NO;
	
  private String STATUS;
	
  private String AMOUNT;
	
  private String ERROR_CODE;
	
  private String ERROR_MSG;
	
  private String ORDER_ID;
	
  private String SUCCESS_TIME;
	
  // getter and setter	
}

Oxm mapping file

Next, we need to tell the object relationship, such as which attribute belong to which xml tag. Let’s register it in oxm-mapping.xml

  • map-to xml : Map to parent xml tag
  • field name   : Java object properties
  • bind-xml     :  Map to xml tag
<mapping>

<class name="com.codeomitted.oxm.response.ResponseParameter">
 <map-to xml="ResponseParameter" />
  <field name="header" type="com.codeomitted.oxm.response.ResponseHeader">
   <bind-xml name="ResponseHeader"/>
  </field>
  <field name="body" type="com.codeomitted.oxm.response.ResponseBody">
   <bind-xml name="ResponseBody"/>
  </field>
</class>

</mapping>

Next we map the rest of the object ResponseHeader, ResponseBody and ResponseItem

<mapping>

<class name="com.codeomitted.oxm.response.ResponseParameter">
 <map-to xml="ResponseParameter" />
  <field name="header" type="com.codeomitted.oxm.response.ResponseHeader">
   <bind-xml name="ResponseHeader"/>
  </field>
  <field name="body" type="com.codeomitted.oxm.response.ResponseBody">
   <bind-xml name="ResponseBody"/>
  </field>
</class>

<class name="com.codeomitted.oxm.response.ResponseHeader">
  <map-to xml="ResponseHeader" />
    <field name="ORD_NO" type="string">
      <bind-xml name="ORD_NO" node="element"/> 
   </field>
   <field name="TOTAL_AMOUNT" type="string"> 
      <bind-xml name="TOTAL_AMOUNT" node="element"/> 
   </field>
   <field name="SUCCESS_AMOUNT" type="string"> 
      <bind-xml name="SUCCESS_AMOUNT" node="element"/> 
   </field>
   <field name="ERROR_CODE" type="string"> 
      <bind-xml name="ERROR_CODE" node="element"/> 
   </field>
   <field name="ERROR_MSG" type="string"> 
      <bind-xml name="ERROR_MSG" node="element"/> 
   </field>
   <field name="SIGNVALUE" type="string"> 
      <bind-xml name="SIGNVALUE" node="element"/> 
   </field>	
</class>  

<class name="com.codeomitted.oxm.response.ResponseBody">
  <map-to xml="ResponseBody" />
    <field name="item" type="com.codeomitted.oxm.response.ResponseItem">
      <bind-xml name="ResponseItem"/>
    </field>
</class>  
   
<class name="com.codeomitted.oxm.response.ResponseItem">
  <map-to xml="ResponseItem" />
     <field name="SEQ_NO" type="string"> 
         <bind-xml name="SEQ_NO" node="element"/> 
     </field>
     <field name="STATUS" type="string"> 
          <bind-xml name="STATUS" node="element"/>    
     </field>
     <field name="AMOUNT" type="string"> 
          <bind-xml name="AMOUNT" node="element"/> 
     </field>
     <field name="ERROR_CODE" type="string"> 
         <bind-xml name="ERROR_CODE" node="element"/> 
     </field>
     <field name="ERROR_MSG" type="string"> 
         <bind-xml name="ERROR_MSG" node="element"/> 
     </field>
     <field name="ORDER_ID" type="string"> 
        <bind-xml name="ORDER_ID" node="element"/> 
     </field>
     <field name="SUCCESS_TIME" type="string"> 
         <bind-xml name="SUCCESS_TIME" node="element"/> 
     </field>	
   </class>   
</mapping>

Service Class

Next we define a interface with 2 methods and create a class implement the interface.

  • objectToXml

  • xmlToObject

@Service
public class OxmServiceImpl implements OxmService {
	
  @Autowired
  private Marshaller marshaller;

  @Autowired
  private Unmarshaller unmarshaller;

  public String objectToXml(Object source) {
    StringResult result = new StringResult();
    try {
      marshaller.marshal(source, result);
    } catch (XmlMappingException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return result.toString();
  }
	
  public Object xmlToObject(String xmlString) {
    StringReader in = new StringReader(xmlString);
    Object obj = null;
    try {
	obj = unmarshaller.unmarshal(new StreamSource(in));
    } catch (XmlMappingException e) {
	e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return obj;
  }
}

ApplicationContext 

@Configuration
@ComponentScan(basePackages="com.codeomitted")
public class ApplicationContext {

	@Bean 
	public CastorMarshaller castorMarshaller() {
		CastorMarshaller marshaller = new CastorMarshaller();
		marshaller.setMappingLocation(new ClassPathResource("/oxm-mapping.xml"));
		return marshaller;
	}
	
	@Bean
	public Marshaller marshaller() {
		return castorMarshaller();
	}
	
	@Bean
	public Unmarshaller unmarshaller() {
		return castorMarshaller();
	}
}

Testing

public class Main {

    public static final String SAMPLE_RESPONSE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ResponseParameter><ResponseHeader><ORD_NO>ABC139-176</ORD_NO><TOTAL_AMOUNT>10000</TOTAL_AMOUNT><SUCCESS_AMOUNT>10000</SUCCESS_AMOUNT><ERROR_CODE>0000</ERROR_CODE><ERROR_MSG>SUCCESS</ERROR_MSG><SIGNVALUE>23h83jwq8</SIGNVALUE></ResponseHeader><ResponseBody><ResponseItem><SEQ_NO>123456789</SEQ_NO><STATUS>1</STATUS><AMOUNT>10000</AMOUNT><ERROR_CODE>0000</ERROR_CODE><ERROR_MSG>SUCCESS</ERROR_MSG><ORDER_ID>ABC139-176</ORDER_ID><SUCCESS_TIME>20150301153205</SUCCESS_TIME></ResponseItem></ResponseBody></ResponseParameter>";
	
    public static void main(String[] args) {
		
      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
      ctx.register(ApplicationContext.class);
      ctx.refresh();
		
      OxmService oxmService = (OxmService) ctx.getBean(OxmService.class);
		
      ResponseParameter response = (ResponseParameter) oxmService.xmlToObject(SAMPLE_RESPONSE);
		
      System.out.println(response.getHeader().getORD_NO());
      System.out.println(response.getHeader().getTOTAL_AMOUNT());
      System.out.println(response.getHeader().getSUCCESS_AMOUNT());
      System.out.println(response.getHeader().getERROR_CODE());
      System.out.println(response.getHeader().getERROR_MSG());
      System.out.println(response.getHeader().getSIGNVALUE());
		
      ctx.close();
    }
}

 

Write a Reply or Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.