Skip to Content
Author's profile photo Former Member

Step-by-Step to learn Java-Mapping with JAXB

Step-by-Step learn JAXB Mapping

Based on this Blog I began to learn JAXB-Mapping:

http://scn.sap.com/people/shabarish.vijayakumar/blog/2012/02/07/forget-sax-and-dom-java-mapping-just-got-cooler-with-jaxb-part-1

This blog gives not every detail and I’m new comer in Java World, therefore it is not easy to finish complete scenario. After hard working I made it and would like to share my experience with you here.

In the above link you can find theories about JAXB. Here I just show what I did in NWDS and PI.

1.   1.  2 external Definitions
ED_EmpSource in Namespace: http://dong.com/javamapping; and ED_EmpTarget in Namespace: http://dong.com/JAXBtest.
Why I do so?
At beginning I tried to use Message Types within one namespace, but this makes some difficulties, i.e. variable names are same and conflict in the same package name.
second reasons: the Error: “unable to marshal type because it is missing an @XmlRootElement annotation”
For more information please refer to the article:
http://www.vineetmanohar.com/2009/09/jaxb-code-snippets-for-beginners/
Therefore the structure of the XSD should look as below: 01_XSD.jpg

As As mentioned in this article: Make sure that the root element is an anonymous complex type and not an instance of a defined type.
The Message Type in PI looks normally like this:
01_MT.jpg

With it you will encounter this XmlRootElement error.

2.   2.  Finish PI Scenario in ESR with Service Interface, Message Mapping and Operation Mapping.

03_MM.jpg
The above activities are classic PI configuration.

What I want to do is concat firstname and lastname into fullname when the country is “India” and I am going to use JAXB Mapping to replace graphic mapping. 

3.   3.  Export 2 external definitions in XSD files locally.

4.   4. Set up external tool in NWDS xjc:
/wp-content/uploads/2012/03/04_xjc_81545.jpg /wp-content/uploads/2012/03/05_xjc_81546.jpg

5.   5. Create a new Java Project: JAXB_Test_Emp
and import the following external jar libraries: 
/wp-content/uploads/2012/03/06_libraries_81547.jpg

6.    6. Create 2 directories: sourceData and targetData

7.  7.   Copy-paste XSDs into the corresponding directories. 
/wp-content/uploads/2012/03/07_xsd_81548.jpg

8.   8. Using XJC to generate the required java classes related to the source and target XSD.
The details of these operations:
click on ource XSD and mark it and then start XJC:
08_xjcGeneration.jpg

9.   9. Make the generate java classes to Source in the project properties. 09_Source.jpg
After that the source and target directories are changed to internal source directory or packages, that you can call them in you java class. /wp-content/uploads/2012/03/10_javaclasses_81552.jpg

10.  10. Create a new package “jaxbtest” and a new class “MM_JAXB_Mapping” /wp-content/uploads/2012/03/11_javaclass_81553.jpg/wp-content/uploads/2012/03/12_addinterface_81557.jpg

11. 11. The codes in MM_JAXB_Mapping Class look like this:

package jaxbtest;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.Reader;

import java.util.List;

import java.util.Map;

import javax.xml.bind.JAXBContext;

import javax.xml.bind.JAXBElement;

import javax.xml.bind.Marshaller;

import javax.xml.bind.Unmarshaller;

import javax.xml.transform.stream.StreamSource;

import com.dong.javamapping.DTEmp;

import com.dong.jaxbtest.MTEmpTarget;

import com.sap.aii.mapping.api.AbstractTransformation;

import com.sap.aii.mapping.api.StreamTransformationException;

import com.sap.aii.mapping.api.TransformationInput;

import com.sap.aii.mapping.api.TransformationOutput;

/**

* @author Rene Dong JAXB Mapping Test in PI 14.03.2012, Germany

*/

public class MM_JAXB_Mapping extends AbstractTransformation {

   InputStream is = null;

   public void transform(TransformationInput arg0, TransformationOutput arg1)

               throws StreamTransformationException {

         getTrace().addInfo(“JAVA Mapping MM_JAXB_Mapping is Initiated”);

         try {

               is = arg0.getInputPayload().getInputStream();

               JAXBContext jaxbContext = JAXBContext.newInstance(DTEmp.class);

               Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();

               JAXBElement<DTEmp> employee_source = (JAXBElement<DTEmp>) unMarshaller

                           .unmarshal(new StreamSource(is), DTEmp.class);

               getTrace().addInfo(“Unmarshall Successful”);

               /*————- Marshal the Target—————-*/

               com.dong.jaxbtest.MTEmpTarget target = new MTEmpTarget();

               List<DTEmp.Employee.Name> EmployeeS = employee_source.getValue()

                           .getEmployee().getName();

               getTrace().addInfo(

                           “Source Employee has (“ + EmployeeS.size()

                                       + “) Employee Knots”);

               for (int i = 0; i < EmployeeS.size(); i++) {

                     DTEmp.Employee.Name NameS = (DTEmp.Employee.Name) EmployeeS

                                 .get(i);

                     String c = NameS.getCountry();

                     if (c.equalsIgnoreCase(“india”)) {

                           MTEmpTarget.Employee emp = new MTEmpTarget.Employee();

                           emp.setFullname(NameS.getFirstname() + ” “

                                       + NameS.getLastname());

                           emp.setCountryTarget(c);

                           target.getEmployee().add(emp);

                     }

               }

               JAXBContext contextTarget = JAXBContext

                           .newInstance(MTEmpTarget.class);

               Marshaller marshallerTarget = contextTarget.createMarshaller();

               marshallerTarget.marshal(target, arg1.getOutputPayload()

                           .getOutputStream());

         } catch (Exception e) {

               getTrace().addWarning(e.toString());

         }

   }

   public String convertInputStreamToString(InputStream in) {

         StringBuffer sb = new StringBuffer();

         try {

               InputStreamReader isr = new InputStreamReader(in);

               Reader reader = new BufferedReader(isr);

               int ch;

               while ((ch = in.read()) > -1) {

                     sb.append((char) ch);

               }

               reader.close();

         } catch (Exception exception) {

         }

         return sb.toString();

   }

   /*

    * (non-Javadoc)

    *

    * @see com.sap.aii.mapping.api.StreamTransformation#setParameter(java.util.Map)

    */

   public void setParameter(Map arg0) {

   }

}

12. 12. Export the whole project as a jar file and save it locally.
/wp-content/uploads/2012/03/13_export_81558.jpg/wp-content/uploads/2012/03/14_export02_81566.jpg

13.  13.Import jar file as imported Archive into PI. 
15_IA.jpg

14.  14. Replace the Message-Mapping in the Operation Mapping with the new Imported Archive.  16_OM.jpg

15.15.  Test in the operation mapping
/wp-content/uploads/2012/03/17_test_81572.jpg

So it works!

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Otto Frost
      Otto Frost

      Instead of using the xjc for generation, you can use the SAP graphical wizards.

      In ESR perspective, click the service interface

      Generate Client

      follow the wizard to generate the artifacts.

      sometimes it is necessary to mess with the classloader, otherwise the marshalling unmarshalling won't work or it is impossinle to create jaxb context

       

      ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
        try {
         Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
      // JAXB coding and mapping

      String contextPath = ItemType.class.getPackage().getName();

      JAXBContext jc = JAXBContext.newInstance(contextPath);

      // more coding

        } finally {
         Thread.currentThread().setContextClassLoader(oldLoader);
        }

      using the wizard avoids using jaxb customizing which can be tricky