Skip navigation.
Downloads | Product Documentation | Support

Programming WebLogic Web Services

# Creating a WebLogic Web Service: A Simple Example

The following sections describe how to create a simple WebLogic Web Service:

- Overview of the Web Service Example
- Building and Running the Trader WebLogic Web Service Example
- Anatomy of the Example

# Overview of the Web Service Example

This example describes the start-to-finish process of implementing, assembling, and deploying the WebLogic Web Service provided as a product example in the directory `WL_HOME``/samples/server/examples/src/examples/webservices/complex/statelessSession`, where `WL_HOME` refers to the main WebLogic Platform directory, such as `d:\beahome\weblogic81`.

The example shows how to create a WebLogic Web Service based on a stateless session EJB. The example uses the `Trader` EJB, one of the EJB 2.0 examples located in the `WL_HOME``/samples/server/examples/src/examples/ejb20/basic/statelessSession` directory.

The `Trader` EJB defines two methods, `buy()` and `sell()`, that take as input a `String` stock symbol and an `int` number of shares to buy or sell. Both methods return a non-built-in data type called `TradeResult`.

When the `Trader` EJB is converted into a Web Service, the two methods become public operations defined in the WSDL of the Web Service. The `Client.java` application uses a JAX-RPC style client API to create SOAP messages that invoke the operations.

# Building and Running the Trader WebLogic Web Service Example

The procedure below describes how to build and run the `WL_HOME``/samples/server/examples/src/examples/webservices/complex/statelessSession` example, using the `build.xml` Ant build file in the example directory to perform all the main steps, such as compiling the EJB Java source code into class files, executing the `servicegen` WebLogic Web Service Ant task, and deploying the Web Service to WebLogic Server. The section Anatomy of the Example describes the main components (such as the stateless session EJB and the non-built-in data type) that make up the example.

Note: It is assumed in this section that you have started the examples WebLogic Server domain that is installed by default with WebLogic Server. The domain directory of the examples server is `WL_HOME``\samples\domains\examples`.

To build and run the sample `Trader` WebLogic Web Service:

1. Open a command window.
2. Set up your environment.

On Windows NT, execute the `setExamplesEnv.cmd` command, located in the directory `WL_HOME``\samples\domains\examples`, where `WL_HOME` is the main directory of your WebLogic Platform installation, such as `d:\beahome\weblogic81`.

On UNIX, execute the `setEnv.sh` command, located in the directory `WL_HOME``/samples/domains/examples`, where `WL_HOME` is the main directory of your WebLogic Platform installation, such as `/beahome/weblogic81`.

3. Change to the `WL_HOME``\samples\server\examples\src\examples\webservices\complex\statelessSession` directory.
4. Assemble and compile the example by executing the Java `ant` utility at the command line:

>     prompt> ant

The `ant` utility uses the `build.xml` build script to perform the following tasks:

- Create an EJB JAR file from the EJB `*.java` files.
- Execute the `servicegen` Ant task which automatically generates the serialization class for the `TradeResult` non-built-in data type, creates the `web-services.xml` file, and packages all these components into a deployable EAR file.
- Deploy the EAR file on WebLogic Server.
- Execute the `clientgen` Ant task to create a local client JAR file that contains all the needed classes and interfaces to invoke the Web Service.
- Compile the `Client.java` client application used to invoke the Web Service.

5. In your development shell, run the `Client` Java application using the following command:

>     prompt> ant run

If the example runs successfully, you should see the following output in both the window from which you ran the client application and the WebLogic Server console window:

>     [java] Buying 100 shares of BEAS.
>     [java] Result traded 100 shares of BEAS
>     [java] Buying 200 shares of MSFT.
>     [java] Result traded 200 shares of MSFT
>     [java] Buying 300 shares of AMZN.
>     [java] Result traded 300 shares of AMZN
>     [java] Buying 400 shares of HWP.
>     [java] Result traded 400 shares of HWP
>     [java] Selling 100 shares of BEAS.
>     [java] Result traded 100 shares of BEAS
>     [java] Selling 200 shares of MSFT.
>     [java] Result traded 200 shares of MSFT
>     [java] Selling 300 shares of AMZN.
>     [java] Result traded 300 shares of AMZN
>     [java] Selling 400 shares of HWP.
>     [java] Result traded 400 shares of HWP

6. Optionally view the Web Service Home Page by entering the following URL in your browser:

>     http://localhost:port/webservice/TraderService

where

- `localhost` refers to the machine on which WebLogic Server is running.
- `port` refers to port on which WebLogic Server is listening.

From the Web Service Home Page you can view the generated WSDL, and test the Web service to make sure it is working correctly.

# Anatomy of the Example

This section describes the following main components of the example you built and ran in Building and Running the Trader WebLogic Web Service Example:

- The EJB Java Interfaces and Implementation Class
- The Non-Built-In Data Type TraderResult
- The EJB Deployment Descriptors
- The servicegen Ant Task That Assembles the Web Service
- The Client Application to Invoke The Web Service

## The EJB Java Interfaces and Implementation Class

The Web Service example is based on a stateless session EJB. This `Trader` EJB defines two methods, `buy()` and `sell()`, that take as input a `String` stock symbol and an `int` number of shares to buy or sell. Both methods return a non-built-in data type called `TraderResult`.

The following Java interfaces and implementation class define the `Trader` EJB:

- Remote Interface (Trader.java)
- Session Bean Implementation Class (TraderBean.java)
- Home Interface (TraderHome.java)

### Remote Interface (Trader.java)

>     package examples.webservices.complex.statelessSession;

>     import java.rmi.RemoteException;
>     import javax.ejb.EJBObject;

>     /**
>      * The methods in this interface are the public face of TraderBean.
>      * The signatures of the methods are identical to those of the EJBean, except
>      * that these methods throw a java.rmi.RemoteException.
>      * Note that the EJBean does not implement this interface. The corresponding
>      * code-generated EJBObject, TraderBeanE, implements this interface and
>      * delegates to the bean.
>      *
>      * @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
>      */
>     public interface Trader extends EJBObject {

>       /**
>        * Buys shares of a stock.
>        *
>        * @param stockSymbol       String Stock symbol
>        * @param shares            int Number of shares to buy
>        * @return                  TradeResult Trade Result
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        */
>       public  TradeResult buy (String stockSymbol, int shares)
>         throws RemoteException;

>       /**
>        * Sells shares of a stock.
>        *
>        * @param stockSymbol       String Stock symbol
>        * @param shares            int Number of shares to sell
>        * @return                  TradeResult Trade Result
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        */
>       public TradeResult sell (String stockSymbol, int shares)
>         throws RemoteException;
>     }

### Session Bean Implementation Class (TraderBean.java)

>     package examples.webservices.complex.statelessSession;

>     import javax.ejb.CreateException;
>     import javax.ejb.SessionBean;
>     import javax.ejb.SessionContext;
>     import javax.naming.InitialContext;
>     import javax.naming.NamingException;

>     /**
>      * TraderBean is a stateless Session Bean. This bean illustrates:
>      * <ul>
>      * <li> No persistence of state between calls to the Session Bean
>      * <li> Looking up values from the Environment
>      * </ul>
>      *
>      * @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
>      */
>     public class TraderBean implements SessionBean {

>       private static final boolean VERBOSE = true;
>       private SessionContext ctx;
>       private int tradeLimit;

>       // You might also consider using WebLogic's log service
>       private void log(String s) {
>         if (VERBOSE) System.out.println(s);
>       }

>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbActivate() {
>         log("ejbActivate called");
>       }

>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbRemove() {
>         log("ejbRemove called");
>       }

>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbPassivate() {
>         log("ejbPassivate called");
>       }

>       /**
>        * Sets the session context.
>        *
>        * @param ctx               SessionContext Context for session
>        */
>       public void setSessionContext(SessionContext ctx) {
>         log("setSessionContext called");
>         this.ctx = ctx;
>       }

>       /**
>        * This method corresponds to the create method in the home interface
>        * "TraderHome.java".
>        * The parameter sets of the two methods are identical. When the client calls
>        * <code>TraderHome.create()</code>, the container allocates an instance of
>        * the EJBean and calls <code>ejbCreate()</code>.
>        *
>        * @exception               javax.ejb.CreateException if there is
>        *                          a communications or systems failure
>        * @see                     examples.ejb11.basic.statelessSession.Trader
>        */
>       public void ejbCreate () throws CreateException {
>         log("ejbCreate called");
>         try {
>           InitialContext ic = new InitialContext();
>           Integer tl = (Integer) ic.lookup("java:/comp/env/tradeLimit");
>           tradeLimit = tl.intValue();
>         } catch (NamingException ne) {
>           throw new CreateException("Failed to find environment value "+ne);
>         }
>       }

>       /**
>        * Buys shares of a stock for a named customer.
>        *
>        * @param customerName      String Customer name
>        * @param stockSymbol       String Stock symbol
>        * @param shares            int Number of shares to buy
>        * @return                  TradeResult Trade Result
>        *                          if there is an error while buying the shares
>        */
>       public TradeResult buy(String stockSymbol, int shares) {
>         if (shares > tradeLimit) {
>           log("Attempt to buy "+shares+" is greater than limit of "+tradeLimit);
>           shares = tradeLimit;
>         }
>         log("Buying "+shares+" shares of "+stockSymbol);
>         return new TradeResult(shares, stockSymbol);
>       }

>       /**
>        * Sells shares of a stock for a named customer.
>        *
>        * @param customerName      String Customer name
>        * @param stockSymbol       String Stock symbol
>        * @param shares            int Number of shares to buy
>        * @return                  TradeResult Trade Result
>        *                          if there is an error while selling the shares
>        */
>       public TradeResult sell(String stockSymbol, int shares) {
>         if (shares > tradeLimit) {
>           log("Attempt to sell "+shares+" is greater than limit of "+tradeLimit);
>           shares = tradeLimit;
>         }
>         log("Selling "+shares+" shares of "+stockSymbol);
>         return new TradeResult(shares, stockSymbol);
>       }
>     }

### Home Interface (TraderHome.java)

>     package examples.webservices.complex.statelessSession;

>     import java.rmi.RemoteException;
>     import javax.ejb.CreateException;
>     import javax.ejb.EJBHome;

>     /**
>      * This interface is the home interface for the TraderBean.java,
>      * which in WebLogic is implemented by the code-generated container
>      * class TraderBeanC. A home interface may support one or more create
>      * methods, which must correspond to methods named "ejbCreate" in the EJBean.
>      *
>      * @author Copyright (c) 1998-2003 by BEA Systems, Inc. All Rights Reserved.
>      */
>     public interface TraderHome extends EJBHome {
>       /**
>        * This method corresponds to the ejbCreate method in the bean
>        * "TraderBean.java".
>        * The parameter sets of the two methods are identical. When the client calls
>        * <code>TraderHome.create()</code>, the container
>        * allocates an instance of the EJBean and calls <code>ejbCreate()</code>.
>        *
>        * @return                  Trader
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        * @exception               CreateException
>        *                          if there is a problem creating the bean
>        * @see                     examples.ejb11.basic.statelessSession.TraderBean
>        */
>       Trader create() throws CreateException, RemoteException;
>     }

## The Non-Built-In Data Type TraderResult

The two methods of the EJB return a non-built-in data type called `TraderResult`. The following Java code describes this data type:

>     package examples.webservices.complex.statelessSession;

>     import java.io.Serializable;

>     /**
>      * This class reflects the results of a buy/sell transaction.
>      *
>      * @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
>      */
>     public final class TradeResult implements Serializable {

>       // Number of shares really bought or sold.
>       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 EJB Deployment Descriptors

The `Trader` EJB defines the following two deployment descriptor files to describe itself:

- ejb-jar.xml
- weblogic-ejb-jar.xml

### ejb-jar.xml

>     <?xml version="1.0"?>

>     <!DOCTYPE ejb-jar PUBLIC
>     '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
>     'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>

>     <ejb-jar>
>       <enterprise-beans>
>         <session>
>           <ejb-name>TraderService</ejb-name>
>           <home>examples.webservices.complex.statelessSession.TraderHome</home>
>           <remote>examples.webservices.complex.statelessSession.Trader</remote>
>           <ejb-class>examples.webservices.complex.statelessSession.TraderBean</ejb-class>
>           <session-type>Stateless</session-type>
>           <transaction-type>Container</transaction-type>
>           <env-entry>
>             <env-entry-name>WEBL</env-entry-name>
>             <env-entry-type>java.lang.Double </env-entry-type>
>             <env-entry-value>10.0</env-entry-value>
>           </env-entry>
>           <env-entry>
>             <env-entry-name>INTL</env-entry-name>
>             <env-entry-type>java.lang.Double </env-entry-type>
>             <env-entry-value>15.0</env-entry-value>
>           </env-entry>
>           <env-entry>
>             <env-entry-name>tradeLimit</env-entry-name>
>             <env-entry-type>java.lang.Integer </env-entry-type>
>             <env-entry-value>500</env-entry-value>
>           </env-entry>
>         </session>
>       </enterprise-beans>
>       <assembly-descriptor>
>         <container-transaction>
>           <method>
>             <ejb-name>TraderService</ejb-name>
>             <method-name>*</method-name>
>           </method>
>           <trans-attribute>Required</trans-attribute>
>         </container-transaction>
>       </assembly-descriptor>
>     </ejb-jar>

### weblogic-ejb-jar.xml

>     <?xml version="1.0"?>

>     <!DOCTYPE weblogic-ejb-jar PUBLIC
>     '-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN'
>     'http://www.bea.com/servers/wls700/dtd/weblogic700-ejb-jar.dtd'>

>     <weblogic-ejb-jar>
>       <weblogic-enterprise-bean>
>         <ejb-name>TraderService</ejb-name>
>         <jndi-name>webservices-complex-statelessession</jndi-name>
>       </weblogic-enterprise-bean>
>     </weblogic-ejb-jar>

## The servicegen Ant Task That Assembles the Web Service

The Ant build file, `build.xml`,contains a call to the `servicegen` Ant task that introspects the `trader.jar` EJB file and:

- Generates all data type components (such as the serialization class).
- Creates the `web-services.xml` deployment descriptor file.
- Packages all components into a deployable `trader.ear` file.

The following snippet from the sample `build.xml` file contains instructions that will build the EAR file into a temporary `build_dir` directory:

>     <target name="build" >
>         <delete dir="build_dir" />
>         <mkdir dir="build_dir" />
>         <copy todir="build_dir" file="trader.jar"/>
>         <servicegen
>           destEar="build_dir/trader.ear"
>           warName="trader.war"
>           contextURI="webservice">
>           <service
>              ejbJar="build_dir/trader.jar"
>              targetNamespace="http://www.bea.com/examples/Trader"
>              serviceName="TraderService"
>              serviceURI="/TraderService"
>              generateTypes="True"
>              expandMethods="True" >
>           </service>
>         </servicegen>
>       </target>

## The Client Application to Invoke The Web Service

The following Java client application shows how to use the JAX-RPC API to invoke the buy and sell operations of the deployed `Trader` Web Service:

>     package examples.webservices.complex.statelessSession;

>     /**
>      * This class illustrates how to use the JAX-RPC API to invoke the TraderService

>      * Web service to perform the following tasks:
>      * <ul>
>      * <li> Buy 100 shares of some stocks
>      * <li> Sell 100 shares of some stocks
>      * </ul>
>      *
>      * The TraderService Web service is implemented using the Trader
>      * stateless session EJB.
>      * * @author Copyright (c) 1998-2003 by BEA Systems, Inc. All Rights Reserved.
>      */

>     public class Client {

>       public static void main(String[] args) throws Exception {

>         // Setup the global JAXM message factory
>         System.setProperty("javax.xml.soap.MessageFactory",
>           "weblogic.webservice.core.soap.MessageFactoryImpl");
>         // Setup the global JAX-RPC service factory
>         System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>         // Parse the argument list
>         Client client = new Client();
>         String wsdl = (args.length > 0? args[0] : null);
>         client.example(wsdl);
>       }

>       public void example(String wsdlURI) throws Exception {

>         TraderServicePort trader = null;
>         if (wsdlURI == null) {
>           trader = new TraderService_Impl().getTraderServicePort();
>         } else {
>           trader = new TraderService_Impl(wsdlURI).getTraderServicePort();
>         }
>         String [] stocks = {"BEAS", "MSFT", "AMZN", "HWP" };

>           // execute some buys
>         for (int i=0; i<stocks.length; i++) {
>           int shares = (i+1) * 100;
>           log("Buying "+shares+" shares of "+stocks[i]+".");
>           TradeResult result = trader.buy(stocks[i], shares);
>           log("Result traded "+result.getNumberTraded()
>               +" shares of "+result.getStockSymbol());
>         }

>         // execute some sells
>         for (int i=0; i<stocks.length; i++) {
>           int shares = (i+1) * 100;
>           log("Selling "+shares+" shares of "+stocks[i]+".");
>           TradeResult result = trader.sell(stocks[i], shares);
>           log("Result traded "+result.getNumberTraded()
>               +" shares of "+result.getStockSymbol());

>         }

>       }

>       private static void log(String s) {
>         System.out.println(s);
>       }

>     }