bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming WebLogic Web Services

Assembling a WebLogic Web Service Manually

The following sections provide information about assembling a WebLogic Web service manually:

- Overview of Assembling a WebLogic Web Service Manually

- Assembling a WebLogic Web Service Manually: Main Steps

- Overview of the web-services.xml File

- Creating the web-services.xml File Manually: Main Steps

- Sample web-services.xml Files

Overview of Assembling a WebLogic Web Service Manually

Assembling a WebLogic Web service refers to gathering all the components of the service (such as the EJB JAR file, the SOAP message handler classes, and so on), generating the web-services.xml deployment descriptor file, and packaging everything into an Enterprise Application EAR file that can be deployed on WebLogic Server.

Typically you never assemble a WebLogic Web service manually, because the procedure is complex and time-consuming. Rather, use the WebLogic Ant tasks such as servicegen, autotype, source2wsdd, and so on to automatically generate all the needed components and package them into a deployable EAR file.

If, however, your Web service is so complex that the Ant tasks are not able to generate the needed components, or you want full control over all aspects of the Web service assembly, then use this chapter as a guide to assembling the Web service manually.

Assembling a WebLogic Web Service Manually: Main Steps

1. Package or compile the backend components that implement the Web service into their respective packages. For example, package stateless session EJBs into an EJB JAR file and Java classes into class files.

   For detailed instructions, see WebLogic Server Application Packaging.

2. Create the Web service deployment descriptor file (web-services.xml).

   For a description of the web-services.xml file, see Overview of the web-services.xml File. For detailed steps for creating the file manually, see Creating the web-services.xml File Manually: Main Steps.

3. If your Web service uses non-built-in data types, create all the needed components, such as the serialization class.

   For detailed information on creating these components manually, see Using Non-Built-In Data Types.

4. Package all components into a deployable EAR file.

   When packaging the EAR file manually, be sure to put the correct Web service components into a Web application WAR file. For details about the WAR and EAR file hierarchy, see The Web Service EAR File Package. For instructions on creating WAR and EAR files, see WebLogic Server Application Packaging.

Overview of the web-services.xml File

The web-services.xml deployment descriptor file contains information that describes one or more WebLogic Web services, such as the backend components that implement the Web service; the non-built-in data types used as parameters and return values; the SOAP message handlers that intercept SOAP messages; and so on. As is true for all deployment descriptors, web-services.xml is an XML file.

Based on the contents of the web-services.xml deployment descriptor file, WebLogic Server dynamically generates the WSDL of a deployed WebLogic Web service. See The WebLogic Web Services Home Page and WSDL URLs for details on getting the URL of the dynamically generated WSDL.

A single WebLogic Web service consists of one or more operations; you can implement each operation using methods of different backend components and SOAP message handlers. For example, an operation might be implemented with a single method of a stateless session EJB or with a combination of SOAP message handlers and a method of a stateless session EJB.

A single web-services.xml file contains a descritpion of at least one, and maybe more, WebLogic Web services.

If you are assembling a Web service manually (necessary, for example, is the service uses SOAP message handlers and handler chains), you need to create the web-services.xml file manually. If you assemble a WebLogic Web service with the servicegen Ant task, you do not need to create the web-services.xml file manually, because the Ant task generates one for you based on its introspection of the EJBs, the attributes of the Ant task, and so on.

Even if you need to manually assemble a Web service, you can use the servicegen Ant task to create a basic template, and then use this document to help you update the generated web-services.xml with the extra information that servicegen does not provide.

Creating the web-services.xml File Manually: Main Steps

The web-services.xml deployment descriptor file describes one or more WebLogic Web service. The file includes information about the operations that make up the Web services, the backend components that implement the operations, data type mapping information about non-built-in data types used as parameters and return values of the operations, and so on. See Sample web-services.xml Files for complete examples of web-services.xml files that describe different kinds of WebLogic Web services. You can use any text editor to create the web-services.xml file.

For detailed descriptions of each element described in this section, see WebLogic Web Service Deployment Descriptor Elements.

The following example shows a simple web-services.xml file:

>     <web-services>
>          <web-service name="stockquotes" targetNamespace="http://example.com"
>                       uri="/myStockQuoteService">
>               <components>
>                    <stateless-ejb name="simpleStockQuoteBean">
>                         <ejb-link path="stockquoteapp.jar#StockQuoteBean" />
>                    </stateless-ejb>
>               </components>
>               <operations>
>                    <operation method="getLastTradePrice"
>                               component="simpleStockQuoteBean" />
>               </operations>
>          </web-service>
>     </web-services>

To create the web-services.xml file manually:

1. Create the root <web-services> element which contains all other elements:

   >     <web-services>
   >     ...
   >     </web-servives>

2. If one or more of your Web services include SOAP message handlers to intercept SOAP messages, create a <handler-chains> child element of the <web-services> root element and include all the relevant child elements to describe the handlers in the handler chain, the order in which they should be invoked, and so on. For details, see Updating the web-services.xml File with SOAP Message Handler Information.

3. For each Web service you want to define, follow these steps:

   1. Create a <web-service> child element of the <web-services> element. Use the name, targetNamespace, and uri attributes to specify the name of the Web service, its target namespace, and the URI that clients will use to invoke the Web service, as shown in the following example:

      >     <web-service name="stockquote"
      >                  targetNamespace="http://example.com"
      >                  uri="myStockQuoteService">
      >     ...
      >     </web-service>

      To specify that the operations in your Web service are all document-oriented, use the style="document" attribute. The default value of the style attribute is rpc, which means the operations are all RPC-oriented.

   2. Create a <components> child element of the <web-service> element that lists the backend components that implement the operations of the Web service. For details, see Creating the <components> Element.

   3. If the operations in your Web service use non-built-in data types as parameters or return values, add data type mapping information by creating <types> and <type-mapping> child elements of the <web-service> element. For details, see Creating the Data Type Mapping File.

      Note: You do not have to perform this step if the operations of your Web service use only built-in data types as parameters or return values. See Using Built-In Data Types for a list of the supported built-in data types.

   4. Create an <operations> child element of the <web-service> element that lists the operations that make up the Web service:

      >     <operations xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      >     ....
      >     </operations>

   5. Within the <operations> element, list the operations defined for the Web service. For details, see Creating <operation> Elements.

Creating the <components> Element

Use the <components> child element of the <web-service> element to list and describe the backend components that implement the operations of a Web service. Each backend component has a name attribute that you later use when describing the operation that the component implements.

Note: If you are creating a SOAP message handler-only type of Web service in which handlers and handler chains do all the work and never execute a backend component, you do not specify a <components> element in the web-services.xml file. For all other types of Web services you must declare a <components> element.

You can list one of the following types of backend components:

- <stateless-ejb>

  This element describes a stateless EJB backend component. Use either the <ejb-link> child element to specify the name of the EJB and the JAR file where it is located or the <jndi-name> child element to specify the JNDI name of the EJB, as shown in the following example:

  >     <components>
  >       <stateless-ejb name="simpleStockQuoteBean">
  >          <ejb-link path="stockquoteapp.jar#StockQuoteBean" />
  >       </stateless-ejb>
  >     </components>

- <java-class>

  This element describes a Java class backend component. Use the class-name attribute to specify the fully qualified path name of the Java class, as shown in the following example:

  >     <components>
  >        <java-class name="customClass"
  >                    class-name="myclasses.MyOwnClass" />
  >     </components>

Creating <operation> Elements

The <operation> element describes how the public operations of a WebLogic Web service are implemented. (The public operations are those that are listed in the Web service's WSDL and are executed by a client application that invokes the Web service.) The following example shows an <operation> declaration:

>     <operation name="getQuote"
>                component="simpleStockQuoteBean"
>                method="getQuote">
>        <params>
>           <param name="in1" style="in" type="xsd:string" location="Header"/>
>           <param name="in2" style="in" type="xsd:int"  location="Header"/>
>           <return-param name="result" type="xsd:string"  location="Header"/>
>        </params>
>     </operation>

Typically, every instance of an <operation> element in the web-services.xml file includes the name attribute which translates into the public name of the Web service operation. The only exception is when you use the method="*" attribute to specify all methods of an EJB or Java class in a single <operation> element; in this case, the public name of the operation is the name of the method.

Use the attributes of the <operation> element in combination to specify different kinds of operations. For details, see Specifying the Type of Operation.

Use the <params> element to optionally group together the parameters and return value of the operation. For details, see Specifying the Parameters and Return Value of the Operation.

Specifying the Type of Operation

Use the attributes of the <operation> element in different combination to identify the type of operation, the type of component that implements it, whether it is a one-way operation, and so on.

Note: For clarity, the examples in this section do not declare any parameters.

The following examples show how to declare a variety of different operations:

- To specify that an operation is implemented with just a method of a stateless session EJB, use the name, component, and method attributes, as shown in the following example:

  >     <operation name="getQuote"
  >                component="simpleStockQuoteBean"
  >                method="getQuote">
  >     </operation>

- To specify with a single <operation> element that you want to include all the methods of an EJB or Java class, use the method="*" attribute; in this case, the public name of the operation is the name of the method:

  >     <operation component="simpleStockQuoteBean"
  >                method="*">
  >     </operation>

- To specify that an operation only receives data and does not return anything to the client application, add the invocation-style attribute:

  >     <operation name="getQuote"
  >                component="simpleStockQuoteBean"
  >                method="getQuote(java.lang.String)"
  >                invocation-style="one-way">
  >     </operation>

  The example also shows how to specify the full signature of a method with the method attribute. You only need to specify the full signature of a method if your EJB or Java class overloads the method and you thus need to unambiguously declare which method you are exposing as a Web service operation.

- To specify that an operation is implemented with a SOAP message handler chain and a method of a stateless session EJB, use the name, component, method, and handler-chain attributes:

  >     <operation name="getQuote"
  >                component="simpleStockQuoteBean"
  >                method="getQuote"
  >                handler-chain="myHandler">
  >     </operation>

- To specify that an operation is implemented with just a SOAP message handler chain, use just the name and handler-chain attributes:

  >     <operation name="justHandler"
  >                handler-chain="myHandler">

  >     </operation>

Specifying the Parameters and Return Value of the Operation

Use the <params> element to explicitly declare the parameters and return values of the operation.

You do not have to explicitly list the parameters or return values of an operation. If an <operation> element does not have a <params> child element, WebLogic Server introspects the backend component that implements the operation to determine its parameters and return values. When generating the WSDL of the Web service, WebLogic Server uses the names of the corresponding method's parameters and return value.

You explicitly list an operation's parameters and return values when you need to:

- Make the name of the parameters and return values in the generated WSDL different from those of the method that implements the operation.

- Map a parameter to a name in the SOAP header request or response.

- Use out or in-out parameters.

Use the <param> child element of the <params> element to specify a single input parameter and the <return-param> child element to specify the return value. You must list the input parameters in the same order in which they are defined in the method that implements the operation. The number of <param> elements must match the number of parameters of the method. You can specify only one <return-param> element.

Use the attributes of the <param> and <return-param> elements to specify the part of the SOAP message where parameter is located (the body or header), the type of the parameter (in, out, or in-out), and so on. You must always specify the XML Schema data type of the parameter using the type attribute. The following examples show a variety of input and return parameters.

- To specify that a parameter is a standard input parameter, located in the header of the request SOAP message, use the style and location attributes as shown:

  >     <param name="inparam" style="in"
  >            location = "Header" type="xsd:string" />

- Out and in-out parameters enable an operation to return more than one return value (in addition to using the standard <return-value> element.) The following sample <param> element shows how to specify that a parameter is an in-out parameter, which means that it acts as both an input and output parameter:

  >     <param name="inoutparam" style="inout"
  >            type="xsd:int" />

  Because the default value of the location attribute is Body, both the input and output parameter values are found in the body of the SOAP message.

- The following example shows how to specify a standard return value located in the header of the response SOAP message:

  >      <return-param name="result" location="Header"
  >                    type="xsd:string" />

Optionally use the <fault> child element of the <params> element to specify your own Java exception that is thrown if there is an error while invoking the operation. This exception will be thrown in addition to the java.rmi.RemoteException exception. For example:

>     <fault name="MyServiceException"
>            class-name="my.exceptions.MyServiceException" />

Sample web-services.xml Files

The following sections describe sample web-services.xml files for the following types of WebLogic Web services:

- EJB Component Web Service With Built-In Data Types

- EJB Component Web Service With Non-Built-In Data Types

- EJB Component and SOAP Message Handler Chain Web Service

- SOAP Message Handler Chain-Only Web Service

EJB Component Web Service With Built-In Data Types

One kind of WebLogic Web service is implemented using a stateless session EJB whose parameters and return values are one of the built-in data types. The following Java interface is an example of such an EJB:

>     public interface SimpleStockQuoteService extends javax.ejb.EJBObject {
>      public float getLastTradePrice(String ticker) throws java.rmi.RemoteException;
>     }

The web-services.xml deployment descriptor for a Web service implemented with this sample EJB can be as follows:

>     <web-services>
>          <web-service name="stockquotes" targetNamespace="http://example.com"
>                       uri="/myStockQuoteService">
>               <components>
>                    <stateless-ejb name="simpleStockQuoteBean">
>                         <ejb-link path="stockquoteapp.jar#StockQuoteBean" />
>                    </stateless-ejb>
>               </components>
>               <operations>
>                    <operation method="getLastTradePrice"
>                               component="simpleStockQuoteBean" />
>               </operations>
>          </web-service>
>     </web-services>

The example shows a Web service called stockquotes. The Web service is implemented with a stateless session EJB whose <ejb-name> in the ejb-jar.xml file is StockQuoteBean and is packaged in the EJB JAR file called stockquoteapp.jar. The internal name of this component is simpleStockQuoteBean. The Web service has one operation, called getLastTradePrice, the same as the EJB method name. The input and output parameters are inferred from the method signature and thus do not need to be explicitly specified in the web-services.xml file.

Note: The servicegen Ant task does not include the methods of EJBObject when generating the list of operations in the web-services.xml file.

The previous example shows how to explicitly list an operation of a Web service. You can, however, implicitly expose all the public methods of an EJB by including just one <operation method="*"> element, as shown in the following example:

>     <operations>
>          <operation method="*"
>                     component="simpleStockQuoteBean" />
>     </operations>

If your Web service supports only HTTPS, then use the protocol attribute of the <web-service> element, as shown in the following example:

>     <web-service name="stockquotes"
>                  targetNamespace="http://example.com"
>                  uri="/myStockQuoteService"
>                  protocol="https" >
>     ...
>     </web-service>

EJB Component Web Service With Non-Built-In Data Types

A more complex type of Web service is one whose operations take non-built-in data types as parameters or return values. Because these non-built-in data types do not directly map to a XML/SOAP data type, you must describe the data type in the web-services.xml file.

For example, the following interface describes an EJB whose two methods return a TradeResult object:

>     public interface Trader extends EJBObject {
>        public TradeResult buy (String stockSymbol, int shares)
>            throws RemoteException;
>        public TradeResult sell (String stockSymbol, int shares)
>            throws RemoteException;
>     }

The TradeResult class looks like the following:

>     public class TradeResult implements Serializable {

>       private int    numberTraded;
>       private String stockSymbol;

>       public TradeResult() {}

>       public TradeResult(int nt, String ss) {
>         numberTraded = nt;
>         stockSymbol  = ss;
>       }

>       public int getNumberTraded() { return numberTraded; }
>       public void setNumberTraded(int numberTraded) {
>          this.numberTraded = numberTraded; }

>       public String getStockSymbol() { return stockSymbol; }
>       public void setStockSymbol(String stockSymbol) {
>          this.stockSymbol = stockSymbol; }
>     }

The following web-services.xml file describes a Web service implemented with this EJB:

>     <web-services>

>       <web-service name="TraderService"
>                    uri="/TraderService"
>                    targetNamespace="http://www.bea.com/examples/Trader">

>         <types>
>           <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>                       xmlns:stns="java:examples.webservices"
>                       attributeFormDefault="qualified"
>                       elementFormDefault="qualified"
>                        targetNamespace="java:examples.webservices">
>             <xsd:complexType name="TradeResult">
>                <xsd:sequence><xsd:element maxOccurs="1" name="stockSymbol"
>                                           type="xsd:string" minOccurs="1">
>                              </xsd:element>
>                              <xsd:element maxOccurs="1" name="numberTraded"
>                                             type="xsd:int" minOccurs="1">
>                               </xsd:element>
>                </xsd:sequence>
>             </xsd:complexType>
>           </xsd:schema>
>          </types>

>         <type-mapping>
>           <type-mapping-entry
>                 deserializer="examples.webservices.TradeResultCodec"
>                 serializer="examples.webservices.TradeResultCodec"
>                 class-name="examples.webservices.TradeResult"
>                 xmlns:p1="java:examples.webservices"
>                 type="p1:TradeResult" >
>          </type-mapping-entry>
>         </type-mapping>

>         <components>
>           <stateless-ejb name="ejbcomp">
>             <ejb-link path="trader.jar#TraderService" />
>           </stateless-ejb>
>         </components>

>         <operations>
>           <operation method="*" component="ejbcomp">
>           </operation>
>         </operations>

>       </web-service>

>     </web-services>

In the example, the <types> element uses XML Schema notation to describe the XML representation of the TradeResult data type. The <type-mapping> element contains an entry for each data type described in the <types> element (in this case there is just one: TradeResult.) The <type-mapping-entry> lists the serialization class that converts the data between XML and Java, as well as the Java class file used to create the Java object.

EJB Component and SOAP Message Handler Chain Web Service

Another type of Web service is implemented with both a stateless session EJB backend component and a SOAP message handler chain that intercepts the request and response SOAP message. The following sample web-services.xml file describes such a Web service:

>     <web-services>
>         <handler-chains>
>             <handler-chain name="submitOrderCrypto">
>                 <handler class-name="com.example.security.EncryptDecrypt">
>                     <init-params>
>                        <init-param name="elementToDecrypt" value="credit-info" />
>                        <init-param name="elementToEncrypt" value="order-number" />
>                     </init-params>
>                 </handler>
>             </handler-chain>
>         </handler-chains>

>         <web-service targetNamespace="http://example.com" name="myorderproc"
>                      uri="myOrderProcessingService">
>             <components>
>                 <stateless-ejb name="orderbean">
>                    <ejb-link path="myEJB.jar#OrderBean" />
>                 </stateless-ejb>
>             </components>
>             <operations xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
>                 <operation name="submitOrder" method="submit"
>                            component="orderbean"
>                            handler-chain="submitOrderCrypto" >
>                    <params>
>                      <param name="purchase-order" style="in" type="xsd:anyType" />
>                      <return-param name="order-number" type="xsd:string" />
>                    </params>
>                 </operation>
>             </operations>
>         </web-service>
>     </web-services>

The example shows a Web service that includes a SOAP message handler-chain called submitOrderCrypto used for decrypting and encrypting information in the SOAP request and response messages. The handler chain includes one handler, implemented with the com.example.security.EncryptDecrypt Java class. The handler takes two initialization parameters that specify the elements in the SOAP message that need to be decrypted and encrypted.

The Web service defines one stateless session EJB backend component called orderbean.

The submitOrder operation shows how to combine a handler-chain with a backend component by specifying the method, component, and handler-chain attributes in combination. When a client application invokes the submitOrder operation, the submitOrderCrypto handler chain first processes the SOAP request, decrypting the credit card information. The handler chain then invokes the submit() method of the orderbean EJB, passing it the modified parameters from the SOAP message, including the purchase-order input parameter. The submit() method then returns an order-number, which is encrypted by the handler chain, and the handler chain finally sends a SOAP response with the encrypted information to the client application that originally invoked the submitOrder operation.

SOAP Message Handler Chain-Only Web Service

You can also implement a WebLogic Web service with just a SOAP message handler chain and never invoke a backend component. This type of Web service might be useful, for example, as a front end to an existing workflow processing system. The handler chain simply takes the SOAP message request and hands it over to the workflow system, which performs all the further processing.

The following sample web-services.xml file describes such a Web service:

>     <web-services>
>         <handler-chains>
>            <handler-chain name="enterWorkflowChain">
>                <handler class-name="com.example.WorkFlowEntry">
>                    <init-params>
>                        <init-param name="workflow-eng-jndi-name"
>                                    value="workflow.entry" />
>                     </init-params>
>                </handler>
>            </handler-chain>
>         </handler-chains>

>         <web-service targetNamespace="http://example.com"
>                       name="myworkflow" uri="myWorkflowService">
>             <operations xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
>                <operation name="enterWorkflow"
>                           handler-chain="enterWorkflowChain"
>                           invocation-style="one-way" />
>             </operations>
>         </web-service>
>     </web-services>

The example shows a Web service that includes one SOAP message handler chain, called enterWorkflowChain. This handler chain has one handler, implemented with the Java class com.example.WorkFlowEntry, that takes as an initialization parameter the JNDI name of the existing workflow system.

The Web service defines one operation called enterWorkflow. When a client application invokes this operation, the enterWorkflowChain handler chain takes the SOAP message request and passes it to the workflow system running on WebLogic Server whose JNDI name is workflow.entry. The operation is defined as asynchronous one-way, which means that the client application does not receive a SOAP response.

Note that because the enterWorkflow operation does not specify the method and component attributes, no backend component is ever invoked directly by the Web service. This also means that the web-services.xml file does not need to specify a <components> element.