![]() |
![]() |
e-docs > WebLogic Server > Programming WebLogic Web Services > Using Non-Built-In Data Types |
Programming WebLogic Web Services
|
The following sections describe how to use non-built-in data types in WebLogic Web services:
Overview of Using Non-Built-In Data Types
You can create a WebLogic Web service that uses non-built-in data types as the Web service parameters and return value. Non-built-in data types are defined as data types other than the supported built-in data types, such as int and String. For the full list of built-in types, see Using Built-In Data Types.
WebLogic Server transparently handles the conversion of the built-in data types between their XML and Java representation. However, if your Web service operation uses non-built-in data types, you must provide the following information so that WebLogic Server can perform the conversion:
WebLogic Server includes the servicegen and autotype Ant tasks which automatically generate the preceding components by introspecting the stateless session EJB or Java class backend component for your Web service. These Ant tasks can handle many non-built-in data types, so most programmers will not ever have to create the components manually.
Sometimes, however, you may need to create the non-built-in data type components manually. Your data type may be so complex that the Ant task cannot correctly generate the components. Or maybe 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.
For a full list of the supported non-built-in data types, see Non-Built-In Data Types Supported by servicegen and autotype Ant Tasks.
For procedural instructions on using servicegen and autotype, see Assembling WebLogic Web Services Using Ant Tasks. For reference information, see Web Service Ant Tasks and Command-Line Utilities.
Creating Non-Built-In Data Types Manually: Main Steps
The following procedure describes how to create non-built-in data types and use the servicegen Ant task to create a deployable Web service:
Writing the XML Schema Data Type Representation
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.
Warning: XML Schema is a powerful and complex data description language, and its use is not recommended for the faint of heart.
The following example shows the XML Schema that describes a non-built-in data type called EmployBean:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:examples.newTypes"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="java:examples.newTypes">
<xsd:complexType name="EmployeeBean">
<xsd:sequence>
<xsd:element name="name"
type="xsd:string"
nillable="true"
minOccurs="1"
maxOccurs="1">
</xsd:element>
<xsd:element name="id"
type="xsd:int"
minOccurs="1"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
The following XML shows an instance of the EmployeeBean data type:
<EmployeeBean>
<name>Beverley Talbott</name>
<id>1234</id>
</EmployeeBean>
For detailed information about using XML Schema notation to describe your non-built-in data type, see the XML Schema specification.
Writing the Java Data Type Representation
You use the Java representation of the non-built-in data type in your EJB or Java class that implements the Web service operation.
The following example shows one possible Java representation of the EmployeeBean data type whose XML representation is described in the preceding section:
package examples.newTypes;
/**
* @author Copyright (c) 2002 by BEA Systems. All Rights Reserved.
*/
public final class EmployeeBean {
private String name = "John Doe";
private int id = -1;
public EmployeeBean() {
}
public EmployeeBean(String n, int i) {
name = n;
id = i;
}
public String getName() {
return name;
}
public void setName(String v) {
this.name = v;
}
public int getId() {
return id;
}
public void setId(int v) {
this.id = v;
}
public boolean equals(Object obj) {
if (obj instanceof EmployeeBean) {
EmployeeBean e = (EmployeeBean) obj;
return (e.name.equals(name) && (e.id == id));
}
return false;
}
}
Writing the Serialization Class
The serialization class performs the actual conversion of your data between its XML and Java representations. You write only one class that contains methods to serialize and deserialize your data. In the class you use the WebLogic XML Streaming API to process the XML data.
The WebLogic XML Streaming API provides an easy and intuitive way to consume and generate XML documents. It enables a procedural, stream-based handling of XML documents.
For detailed information on using the WebLogic XML Streaming API, see Programming WebLogic XML.
The following example shows a class that uses the XML Streaming API to serialize and deserialize the data type described in Writing the XML Schema Data Type Representation and Writing the Java Data Type Representation; the procedure after the example lists the main steps to create such a class:
package examples.newTypes;
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;
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;
public final class EmployeeBeanCodec extends
weblogic.webservice.encoding.AbstractCodec
{
public void serialize(Object obj,
XMLName name,
XMLOutputStream writer,
SerializationContext context)
throws SerializationException
{
EmployeeBean emp = (EmployeeBean) obj;
try {
//outer start element
writer.add(ElementFactory.createStartElement(name));
//employee name element
writer.add(ElementFactory.createStartElement("name"));
writer.add(ElementFactory.createCharacterData(emp.getName()));
writer.add(ElementFactory.createEndElement("name"));
//employee id element
writer.add(ElementFactory.createStartElement("id"));
String id_string = Integer.toString(emp.getId());
writer.add(ElementFactory.createCharacterData(id_string));
writer.add(ElementFactory.createEndElement("id"));
//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.
EmployeeBean employee = new EmployeeBean();
try {
if (reader.skip(name, XMLEvent.START_ELEMENT)) {
StartElement top = (StartElement)reader.next();
//next start element should be the employee name
if (reader.skip(XMLEvent.START_ELEMENT)) {
StartElement emp_name = (StartElement)reader.next();
//assume that the next element is our name character data
CharacterData cdata = (CharacterData) reader.next();
employee.setName(cdata.getContent());
} else {
throw new DeserializationException("employee name not found");
}
//next start element should be the employee id
if (reader.skip(XMLEvent.START_ELEMENT)) {
StartElement emp_id = (StartElement)reader.next();
//assume that the next element is our id character data
CharacterData cdata = (CharacterData) reader.next();
employee.setId(Integer.parseInt(cdata.getContent()));
} else {
throw new DeserializationException("employee id 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 employee;
}
public Object deserialize(XMLName name,
Attribute att,
DeserializationContext context)
throws DeserializationException
{
//NOTE: not used in this example
// extract the desired information out of att, consuming the
// entire element representing the type,
// construct your object, and return it.
return new EmployeeBean();
}
}
To create the serialization class using the WebLogic XML Streaming API, follow these steps:
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;
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;
weblogic.webservice.encoding.AbstractCodec
void serialize(Object obj,
XMLName name,
XMLOutputStream writer,
SerializationContext context)
throws SerializationException;
Object deserialize(XMLName name,
XMLInputStream reader,
DeserializationContext context)
throws DeserializationException;
The XML that you want to deserialize is contained in the XMLInputStream parameter. Use the WebLogic XML Streaming API to parse the XML and convert it into the returned Object. The XMLName parameter contains the expected name of the XML element.
Call the deserialize() method recursively to build contained Objects.
When you use the XML Streaming API to read the stream of events that make up your XML document, be sure you always finish reading an element all the way up to and including the EndElement event, rather than finish reading once you have read all the actual data. If you finish before reaching an EndElement event, the deserialization of subsequent elements might fail.
Object deserialize(XMLName name,
Attribute att,
DeserializationContext context)
throws DeserializationException;
Creating the Data Type Mapping File
The data type mapping file is a subset of the web-services.xml deployment descriptor file. It centralizes some of the information about non-built-in data types, such as the name of the Java class that describes the Java representation of the data, the name of the serialization class that converts the data between XML and Java, and so on. The servicegen Ant task uses this data type mapping file when creating the web-services.xml deployment descriptor for the WebLogic Web service that uses the non-built-in data type.
To create the data type mapping file, follow these steps:
<type-mapping>
...
</type-mapping>
The following example shows a possible data type mapping file with one <type-mapping> entry for the XML Schema data type shown in Updating the web-services.xml File With XML Schema Information:
<type-mapping>
<type-mapping-entry
xmlns:p2="java:examples.newTypes"
class-name="examples.newTypes.EmployeeBean"
type="p2:EmployeeBean"
serializer="examples.newTypes.EmployeeBeanCodec">
deserializer="examples.newTypes.EmployeeBeanCodec"
</type-mapping-entry>
</type-mapping>
Updating the web-services.xml File With XML Schema Information
The web-services.xml file generated by servicegen will not have the XML Schema information for the non-built-in data type for which you have created your own custom serialization class. For this reason, you must manually add the XML Schema information to the deployment descriptor, as described in the following steps:
<types>
...
</types>
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:examples.newTypes"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="java:examples.newTypes">
<xsd:complexType name="EmployeeBean">
<xsd:sequence>
<xsd:element name="name"
type="xsd:string"
nillable="true"
minOccurs="1"
maxOccurs="1">
</xsd:element>
<xsd:element name="id"
type="xsd:int"
minOccurs="1"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
![]() |
![]() |
![]() |
![]() |
||
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |