bea.com | products | dev2dev | support | askBEA |
|
e-docs > WebLogic Server > Programming WebLogic Web Services > Creating a WebLogic Web Service: A Simple Example |
Programming WebLogic Web Services |
Creating a WebLogic Web Service: A Simple Example
The following sections describe a simple example of creating a WebLogic Web Service:
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\src\examples\webservices\complex\statelessSession, where WL_HOME refers to the main WebLogic Platform directory.
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\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.
Example of Creating a WebLogic Web Service: Main Steps
To create the sample Trader WebLogic Web Service, follow these steps:
On Windows NT, execute the setExamplesEnv.cmd command, located in the directory WL_HOME\samples\server\config\examples, where WL_HOME is the main directory of your WebLogic Platform.
On UNIX, execute the setEnv.sh command, located in the directory WL_HOME/samples/server/config/examples, where WL_HOME is the main directory of your WebLogic Platform.
$ ant
http://localhost:port/webservice/TraderService
To invoke the Trader Web Service from a Java client application, see the Client.java file in the WL_HOME\samples\server\src\examples\webservices\complex\statelessSession directory.
For instructions for building and running the client application, invoke the WL_HOME\samples\server\src\examples\webservices\complex\statelessSession\package-summary.html Web page in your browser.
Writing the Java Code for the EJB
The sample Trader stateless session EJB contains two public methods: buy() and sell(). 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 TraderResult.
The following Java code is the public interface of the Trader EJB:
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-2002 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;
}
The following Java code is the actual stateless session EJB class:
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-2002 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);
}
}
The following Java code is the Home interface of the Trader EJB:
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-2002 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;
}
Writing the Java Code for the Non-Built-In Data Type
The two methods of the EJB return a non-built-in data type called TraderResult. The following Java code describes this type:
package examples.webservices.complex.statelessSession;
import java.io.Serializable;
/**
* This class reflects the results of a buy/sell transaction.
*
* @author Copyright (c) 1999-2002 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;
}
}
Creating EJB Deployment Descriptors
See Editing XML Files for information on using the BEA XML Editor to create and edit the ejb-jar.xml and weblogic-ejb-jar.xml files.
The following example shows the ejb-jar.xml deployment descriptor that describes the Trader EJB:
<?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>
The following example shows the weblogic-ejb-jar.xml deployment descriptor that describes the Trader EJB:
<?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>
To assemble the EJB class files and deployment descriptors into a trader.jar archive file, follow these steps:
jar cvf pre_trader.jar -C staging_dir .
java weblogic.ejbc pre_trader.jar trader.jar
Creating the build.xml Ant Build File
The Ant build file, build.xml, contains a call to the servicegen Ant task that introspects the trader.jar EJB file, generates all data type components (such as the serialization class), creates the web-services.xml deployment descriptor file, and packages it all up into a deployable trader.ear file.
The following build.xml file contains instructions that will build the EAR file into a temporary build_dir directory :
<project name="webServicesExample" default="build">
<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="web_services">
<service
ejbJar="build_dir/trader.jar"
targetNamespace="http://www.bea.com/examples/Trader"
serviceName="TraderService"
serviceURI="/TraderService"
generateTypes="True"
expandMethods="True" >
</service>
</servicegen>
</target>
</project>