Entering content frame

This graphic is explained in the accompanying text Schema to Java Generator and Serialization Framework Locate the document in its SAP Library structure

Purpose

A schema XML serialization framework is shipped with the SAP J2EE Engine. It contains a Java representation of schema types and serializers that bring out the Java objects to an xml file. The schema XML serialization framework is part of the webservices_lib.jar and is used for generating Java classes from input schemas.

Prerequisites

The following archive files must be included in the classpath variable of your project:

·        SAP_XML_TOOLKIT_LIBS_HOME/lib/sapxmltoolkit.jar

·        SAP_EXCEPTION_LIB_HOME/lib/exception.jar

·        SAP_LOGGING_LIB_HOME/lib/logging.jar

·        SAP_ENGINE_WEBSERVICES_LIBS_HOME/lib/webservices_api.jar

·        SAP_ENGINE_WEBSERVICES_LIBS_HOME/lib/webservices_lib.jar

·        SAP_ENGINE_WEBSERVICES_LIBS_HOME/lib/iq-lib.jar

·        SAP_ENGINE_WEBSERVICES_LIBS_HOME/lib/util.jar

·        SAP_WEBSERVICES_EXT_LIBS_HOME/lib/jax-rpc_api.jar

·        SAP_WEBSERVICES_EXT_LIBS_HOME/lib/saaj-api.jar

If you are using SAP NetWeaver Developer Studio, you can add these jar files by choosing Project ® Properties ® Java Build Path ® Libraries ® Add Variable. Select a variable (for example, SAP_XML_TOOLKIT_LIBS_HOME) and choose Extend. On the window that is displayed, choose an archive inside the directory displayed (if available).

Features

The serialization framework is a set of Java classes that represent schema types, serializer classes, and framework configuration. The webservices_lib.jar contains a command line tool that parses the schema and generates its Java representation. The framework configuration is stored in an xml file in the output package directory called “types.xml”.

The first step is the schema type system definition (file with xsdextension). The following schema is stored in exmple.xsd file.

This graphic is explained in the accompanying text

<?xml version='1.0' encoding='UTF-8' ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name='Node' type='StructureType'/>

<xs:complexType name="StructureType">

  <xs:sequence>  

  <xs:element name='Name' type='xs:string' nillable='true'/>  

  <xs:element name='Description' type='xs:string' minOccurs='0'/>  

  <xs:element name='Price' type='xs:int'/> 

 </xs:sequence>

</xs:complexType>

</xs:schema>

You now have to run the schema command line tool with the example schema above. Enter the following in the command line:

java com.sap.engine.services.webservices.jaxrpc.schema2java.CommandLine example.xsd outputdir example

At this step, we assume that the jar files mentioned above are included in the classpath, and that for the com.sap.engine.services.webservices.jaxrpc.schema2java.CommandLine command line tool the following parameters are specified:

·        path to input schema – path to the example.xsd

·        output directory – outputdir

·        output package – example

The generated files are located in the specified path under the specified package name. If some schemas were imported then the objects generated for them are placed in sub-packages.

This is the output result:

 example.StructureType.java

 example.types.xml

The schema elements are not mapped to the generated classes, but are described in types.xml file. This file is needed to initialize the serialization framework.

Serialization and Deserialization

Xml serialization and deserialization is done using the  com.sap.engine.services.webservices.jaxrpc.encoding.XMLMarshaller class. This class provides a way of serializing and deserializing xml to the Java object using DOM, input/output stream and a file.

To initialize the XMLMarshaller you must have access to the generated types.xml (as input stream or as a file). Also, a classloader to the generated class is required. If the classloader is not given to the init method, a classloader of the instance is used.

A list of possible init methods follows:

This graphic is explained in the accompanying text

//Passes a path to types.xml.

public void init(String typeMappingFile) throws TypeMappingException;

// Passes a path to types.xml and classloader to the generated classes.

public void init(String typeMappingFile, ClassLoader loader) throws TypeMappingException;

// Passes input stream to types.xml.

public void init(InputStream typeMappingStream) throws TypeMappingException;

// Passes input stream to types.xml and a classloader to the generated files.

public void init(InputStream typeMappingStream, ClassLoader loader) throws TypeMappingException;

 

When the XMLMarshaller instance is initialized, you can use it to serialize and deserialize Java objects into xml using the types defined in the schema. Generally, the generated classes should be used as parameters for serialization.

This graphic is explained in the accompanying text

//Serializes Object to some schema element into output file.

public void marshal(Object object, QName schemaelement, String fileName) throws MarshalException;

 

// Deserializes some schema type from DOM element.

public Object unmarshal(Class resultClass, QName elementType, Element inputNode) throws UnmarshalException;

 

// Deserializes some schema element to java object.

public Object unmarshal(Class resultClass, Element inputNode) throws UnmarshalException;

 

// Serializes Object of schema type to DOM node.

public void marshal(Object object, QName elementType, Element outputNode) throws MarshalException;

 

// Serializes object to schema element.

public void marshal(Object object, Element outputnode) throws MarshalException;

 

// Serializes Java object to output stream.

public void marshal(Object object, QName schemaelement, OutputStream output) throws MarshalException;

 

// Serializes to output stream using some schema type and some root node name.

public void marshal(Object object, QName rootNode, QName schemaType, OutputStream output) throws MarshalException;

 

//Serializes info file using some schema type and some name for the root node

public void marshal(Object object, QName rootNode, QName schemaType, String fileName) throws MarshalException;

 

// Unmarshalls schema element from input file.

public Object unmarshal(Class resultClass, QName schemaElement, String inputFile) throws UnmarshalException;

 

// Unmarshalls schema element from input stream.

public Object unmarshalType(Class resultClass, QName schemaType, InputStream input) throws UnmarshalException;

 

// Unmarshalls schema type from input file.

public Object unmarshalType(Class resultClass, QName schemaType, String inputFile) throws UnmarshalException;

 

Example

This example illustrates the usage of serialization and deserialization. It is important to mention that some knowledge of the schema used is required, such as top level element declarations and the types that were defined. This is important because the schema type system is used to deserialize the mapped Java object (schema delivered).

The code below demonstrates serialization to the output stream using the element reference first and then the type reference. It also shows deserialization from the input stream.

This graphic is explained in the accompanying text

import com.sap.engine.services.webservices.jaxrpc.encoding.XMLMarshaller;

import com.sap.engine.services.webservices.jaxrpc.exceptions.TypeMappingException;

import java.io.InputStream;

import java.io.ByteArrayOutputStream;

import java.io.ByteArrayInputStream;

import java.rmi.MarshalException;

import java.rmi.UnmarshalException;

import example.StructureType;

import javax.xml.namespace.QName;

 

public class ExampleSerialze { 

  public static void main(String[] args) throws TypeMappingException, MarshalException, UnmarshalException {   

   // accessing types.xml  

   InputStream typeSystem = ExampleSerialze.class.getClassLoader().getResourceAsStream("/example/types.xml");   

   XMLMarshaller marshaller = new XMLMarshaller();  

   // calling init method   

   marshaller.init(typeSystem);

    // filling output structure  

    StructureType content = new StructureType();  

    content.setName("My Name");  

    content.setDescription("This is my description."); 

    content.setPrice(20);  

    // References to schema components 

    QName elementName = new QName(null,"Node"); 

    QName typeName = new QName(null,"StructureType");

    //Serializing to output stream (System.out) 

    System.out.println("Serialization using element."); 

    marshaller.marshal(content,elementName,System.out); 

    System.out.println("\nSerialization using type."); 

    QName customRootName = new QName("MyNode");  

    marshaller.marshal(content,customRootName,typeName, System.out); 

    System.out.println("\nSerialization into byte buffer.");

    ByteArrayOutputStream output = new ByteArrayOutputStream(); 

    marshaller.marshal(content,elementName,output);  

    // Deserialization from input stream 

    ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());   

    System.out.println("Deserialization from byte buffer using element."); 

    StructureType result = (StructureType)  marshaller.unmarshal(StructureType.class,elementName,input); 

    // Showing deserialized contents  

    System.out.println("Name :"+result.getName()); 

    System.out.println("Description :"+result.getDescription());

    System.out.println("Price :"+result.getPrice()); 

    System.out.println("Deserialization from byte buffer using type."); 

    input.reset();  

    result = (StructureType) marshaller.unmarshalType(StructureType.class,typeName,input); 

    System.out.println("Name :"+result.getName()); 

    System.out.println("Description :"+result.getDescription()); 

    System.out.println("Price :"+result.getPrice());

  }

}

 

 

This graphic is explained in the accompanying text

The currently-used schema does not have targetNamespace defined, therefore namespace is set to null when schema component references are created. If the schema uses target namespace then this must be taken into consideration. For example, if the schema defines targetNamespace="example.com", then the reference to the Node element must be:

QName elementName = new QName("example.com","Node");

 

Leaving content frame