dcsimg
December 7, 2016
Hot Topics:

Building Web Services with User-Defined Data Types

  • February 1, 2005
  • By Nandhini Arumugam
  • Send Email »
  • More Articles »

Introduction

In a real-world scenario, Web services do not always use primitive data types. The real-world objects may be made of complex, user-defined data types. This article explains in detail the procedure for creating and exposing a Web service with user-defined data types deployed in a Weblogic SOAP container on a BEA Weblogic Server 8.x application server.

Aim of the Article

Creating Web services out of complex, user-defined data types remains one of the challenges of the next generation of Web services. In this article, you have an user-defined data type called personSample. You will learn about the creation and deployment of a Web service with personSample being both the input as well as the return type, along with the complete code.

Web Service with User-Defined Data Types

Weblogic Server transparently handles the conversion of the built-in data types between their XML and Java representation. However, if the Web service operation uses non-built-in data types, you must provide necessary information to the Weblogic Server so that it can perform the conversion. There are two ways of doing it:

  1. Using Weblogic Servers servicegen and autotype Ant tasks. Ant tasks will automatically create a Java class, serialization class, and data type mappings and assemble them into a Web service.
  2. Manual handling of user-defined data types. The problem with the autotype Ant task is that if the data type is too complex, autotype will not correctly generate the components. Or, if you want more control over how the data is converted between its XML and Java representations rather than relying on the default conversion procedure used by WebLogic Server. Various components that are required for manual handling are listed below.
    • A Serialization class that converts between the XML and Java representation of the data.
    • A Java class to contain the Java representation of the data type.
    • An XML Schema representation of the data type.
    • Data type mapping information in the web-services.xml deployment descriptor file.

This article concentrates on manually handling Web services with user-defined data types.

Handling User Defined/Non–Built-In Data Types

The following procedure describes how to create non-built-in data types and use the servicegen Ant task to create a deployable Web service.

Creating an XML schema representation of the data type

Web services use SOAP as the message format to transmit data between the service and the client application that invokes the service. Because SOAP is an XML-based protocol, you must use XML Schema notation to describe the structure of non–built-in data types used by Web Service operations.

The following example describes the XML Schema representation for a non–built-in datatype called personSample.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:stns="java:Sample.personSample"
   attributeFormDefault="qualified"
   elementFormDefault="qualified"
   targetNamespace="java:Sample.personSample">
  <xsd:complexType name="personSample">
    <xsd:sequence>
        <xsd:element name="name"
                     type="xsd:string"
                     nillable="true"
                     minOccurs="1"
                     maxOccurs="1">
        </xsd:element>
        <xsd:element name="age"
                     type="xsd:int"
                     minOccurs="1"
                     maxOccurs="1">
        </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

The following XML shows an instance of the personSample data type:

<personSample>
  <name>Gerry</name> 
  <age>25</age>
</personSample>

Creating the Java class that represents the data type

The Java class representation of the user-defined data type is to defined. It will contain the getter and setter methods for various attributes with constructors. The following example shows the Java class representation of the personSample data type.

package Sample;
public final class personSample
{
   String name;
   int age;

   public personSample()
   {}

   public personSample(String name, int age)
   {
      this.name = name;
      this.age = age;
   }

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

   public void setAge(int age)
   {
      this.age = age;
   }

   public String getName()
   {
      return name;
   }

   public int getAge()
   {
      return age;
   }

}

Writing the Serialization Class

The serialization class performs the actual conversion of the data between its XML and Java representations. You can write only one class that contains methods to serialize and deserialize the data. In this class, the WebLogic XML Streaming API are used to process the XML data. These APIs enable a procedural, stream-based handling of XML documents.

The following example shows a personSampleCodec class that uses the XML Streaming API to serialize and deserialize the personSample data type.

package Sample;
// Importing the classes that are required for serialization and
// deserialization
import weblogic.webservice.encoding.AbstractCodec;
import weblogic.xml.schema.binding.DeserializationContext;
import weblogic.xml.schema.binding.DeserializationException;
import weblogic.xml.schema.binding.Deserializer;
import weblogic.xml.schema.binding.SerializationContext;
import weblogic.xml.schema.binding.SerializationException;
import weblogic.xml.schema.binding.Serializer;
// importing the WebLogic XML Streaming API classes
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.ElementFactory;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLOutputStream;
import weblogic.xml.stream.XMLStreamException;
// This class extends the weblogic.webservice.encoding.AbstractCodec
// class.
public final class personSampleCodec extends
   weblogic.webservice.encoding.AbstractCodec
{
public void serialize(Object obj,XMLName name,XMLOutputStream writer,
                      SerializationContext context)throws
                     SerializationException
{
  personSample personSample = (personSample) obj;
  try
  {
  //outer start element
  writer.add(ElementFactory.createStartElement(name));
  //personSample_ name element
  writer.add(ElementFactory.createStartElement("name"));
 writer.add(ElementFactory.createCharacterData(personSample.getName()));
  writer.add(ElementFactory.createEndElement("name"));
  //personSample_ age element
  writer.add(ElementFactory.createStartElement("age"));
  String age_string = Integer.toString(personSample.getAge());
  writer.add(ElementFactory.createCharacterData(age_string));
  writer.add(ElementFactory.createEndElement("age"));
  //outer end element
  writer.add(ElementFactory.createEndElement(name));
  }
  catch(XMLStreamException xse)
  {
    throw new SerializationException("stream error", xse);
  }
 }

public Object deserialize(XMLName name,XMLInputStream reader,
                          DeserializationContext context)
                         throws DeserializationException
{
  // extract the desired information out of reader, consuming the
  // entire element representing the type, construct your
  // object, and return it.
  personSample personSample_ = new personSample();
  try
  {
    if (reader.skip(name, XMLEvent.START_ELEMENT))
    {
      StartElement top = (StartElement)reader.next();
      //next start element should be the name
      if (reader.skip(XMLEvent.START_ELEMENT))
      {
    StartElement personSample_name = (StartElement)reader.next();
        //assume that the next element is our name character data
        CharacterData cdata = (CharacterData) reader.next();
        personSample_.setName(cdata.getContent());
       }
       else
       {
          throw new DeserializationException
            ("personSample_ name not found");
       }
       //next start element should be the personSample_ age
       if (reader.skip(XMLEvent.START_ELEMENT))
       {
        StartElement personSample_id = (StartElement)reader.next();
        //assume that the next element is our age character data
        CharacterData cdata = (CharacterData) reader.next();
        personSample_.setAge(Integer.parseInt(cdata.getContent()));
       }
       else
       {
          throw new DeserializationException
            ("personSample_ age not found");
       }
       //we must consume our entire element to leave the stream in
       //a good state for any other deserializer
      if (reader.skip(name, XMLEvent.END_ELEMENT))
      {
        XMLEvent end = reader.next();
      }
      else
      {
        throw new DeserializationException
          ("expected end element not found");
      }
    }
    else
    {
      throw new DeserializationException
        ("expected start element not found");
    }
  }
 catch (XMLStreamException xse)
 {
 throw new DeserializationException("stream error", xse);
 }
 return personSample_;
 }
}




Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel