J2EE Sample Code using a Stateful Session EJB in a Web Application

The following code sample illustrates how to use a stateful J2EE session EJB defined for the task file. This sample assumes that you have deployed a J2EE Session EJB application to your application server with a JNDI name of AccountQueryStatefulEJB.

Note You can access stateless EJBs as easily as you can stateful EJBs. The differences are noted in the code samples below.

This sample uses AccountQuery task file with the AccountLookupTask. This task uses an AccountNumber and returns the account Balance.

Create and deploy the session EJB application

In MCS, create and deploy an application to your selected application server. Note the session EJB JNDI name. For instructions, see How to Create and Deploy J2EE Session EJBs.

Creating a WAR

To distribute a Web application, you must package it in a Web application archive (WAR). The WAR supports SunOne, WebLogic, WebSphere, and Oracle, with some minor differences that are noted below. Each file name is linked to its sample code.

StatefulEjbSample.war:

Deploying a WAR

After you have deployed the Web application (WAR), you can access it through the following URL:

http://machine:port/StatefulEjbSample/index.jsp
This application server
Uses this default port...
SunOne 81 (If IIS is already installed and port 80 is being used)
WebLogic 7001
WebSphere 9080
Oracle9i 7777
Note If you are using Oracle as your application server, you will have to download the J2EE Session EJB application and repackage it with the web application. See sample code for Oracle, orion-web.xml

Stateful versus Stateless Session EJBs

When using a stateful session EJB you must save the reference to the bean instance, use that instance to execute tasks, (which may include task chaining), and then call the remove method when you are finished to free resources so others may use them.

When using a stateless session EJB you can save the reference between calls in order to save overhead. However, while basically the same code will work for either type of bean, the remove action is not required when you are using stateless session EJBs.

Source code for index.jsp

<%@page contentType="text/html"%>

<%@ page import="javax/naming.InitialContext"%>
<%@ page import="javax.rmi.PortableRemoteObject"%>
<%@ page import="AccountQueryStateful.AccountQueryStatefulEJB"%>
<%@ page import="AccountQueryStateful.AccountQueryStatefulEJBHome"%>
<%@ page import="AccountQueryStateful.AccountLookupTaskInput.AccountLookupTaskScreenInputs"%> 
<%@ page import="AccountQueryStateful.AccountLookupTaskOutput.AccountLookupTaskScreenOutputs"%> 

<%
	AccountQueryStatefulEJB ejb = "null";
	String AccountNumber = request.getParameter ("AccountNumber");
	String Balance = "";
	
	if (AccountNumber == null)
	{
		AccountNumber = "1000";
	}

//get the ejb out of the session object

ejb =(AccountQueryStatefulEBJ) session.getAttribute ("ejb");
if ("Execute".equals (request.getParameter ("Execute")))
{
	if (ejb == null)
{	
    //couldn't find the ejb, create new one
javax.naming.InitialContext ic="new javax.naming.InitialContext ( );
	Object ref= ic.lookup("java:comp/env/ejb/AccountQueryStatefulEJB");
		AccountQueryStatefulEJBHome home = null;
		home = (AccountQueryStatefulEJBHome)
PortableRemoteObjec.narrow (ref, AccountQueryStatefulEJBHome.class);
		ejb = home.create ( );
//save ejb instance in the session object for future reference
	session.setAttribute("ejb", ebj);
}

// create screen inputs object, define screen output variable
        AccountQueryStateful.AccountLookupTaskInput.AccountLookupTaskScreenInputs si = new AccountQueryStateful.AccountLookupTaskInput.AccountLookupTaskScreenInputs();
        AccountQueryStateful.AccountLookupTaskOutput.AccountLookupTaskScreenOutputs so = null;

        // set task inputs
        si.setAccountNumber(AccountNumber);
        // ...

        // execute task with inputs and collect outputs
        so = ejb.AccountLookupTask(si);

        // get task outputs
        Balance = so.getBalance();
        /*
        // Getting hierarchical values from outputs (table data).
        AccountQueryStateful.AccountDetailsOutput.Table1 table1 = so.getTable1();
        AccountQueryStateful.AccountDetailsOutput.Table1_Row table1_row0 = table1.getTable1_Row(0);
        String date0 = table1_row0.getDate();
        String amount0 = table1_row0.getAmount();
        AccountQueryStateful.AccountDetailsOutput.Table1_Row table1_row1 = table1.getTable1_Row(1);
        String date1 = table1_row1.getDate();
        String amount1 = table1_row1.getAmount();
        */

    }
    else if ("Remove".equals(request.getParameter("Remove")))
    {
        if (ejb != null)
        {
            // remove stateful ejb resources
            ejb.remove();
            // cleanup session object, etc.
            session.removeAttribute("ejb");
            ejb = null;
        }
    }

%>
<html>
<head>
 <title> Stateful Ejb Sample </title>
</head>
<body>
<b> Stateful Ejb Sample</b >

<FORM action='<%=request.getRequestURI()%>' method='POST'>
Account Number:
<INPUT type='TEXT' name='AccountNumber' size='10' value='<%=AccountNumber%>'>
<br>

Balance:
<b><%=Balance%></b>
<br>

<INPUT type='SUBMIT' name='Execute' value='Execute'>
<INPUT type='SUBMIT' name='Remove' value='Remove'<%= ejb == null ? " disabled='true'" : ""%>>

</FORM>
</body>
</html>

Source code for Xsun-web.xml

Required when deploying to SunOne.

Sample Code:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sun-web-app PUBLIC
 '-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 7.0 Servlet 2.3//EN'
 'http://www.sun.com/software/sunone/appserver/dtds/sun-web-app_2_3-0.dtd'>

<sun-web-app>
	<session-config>
		<session-manager persistence-type="memory">
			<manager-properties/>
			<store-properties/>
		</session-manager>
		<session-properties/>
		<cookie-properties/>
	</session-config>
	<ejb-ref>
		<ejb-ref-name>ejb/AccountQueryStatefulEJB</ejb-ref-name>
		<jndi-name>AccountQueryStatefulEJB</jndi-name>
	</ejb-ref>
	<cache max-entries="4096" timeout-in-seconds="30" enabled="false">
		<default-helper/>
	</cache>
	<jsp-config>
		<property name="classdebuginfo" value="true">
			<description>Enable debug info compilation in the generated servlet class</description>
		</property>
		<property name="mappedfile" value="true">
			<description>Maintain a one-to-one correspondence between static content and the generated servlet class' java code</description>
		</property>
	</jsp-config>
</sun-web-app>

Source code for web.xml

Required for all application servers.

Sample code:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC
 '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
 'http://java.sun.com/dtd/web-app_2_3.dtd'>

<web-app>
	<display-name>StatefulEjbSample</display-name>
	<session-config>
		<session-timeout> 30 </session-timeout>
	</session-config>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<ejb-ref>
		<ejb-ref-name>ejb/AccountQueryStatefulEJB</ejb-ref-name>
		<ejb-ref-type>Session</ejb-ref-type>
		<home>AccountQueryStateful.AccountQueryStatefulEJBHome</home>
		<remote>AccountQueryStateful.AccountQueryStatefulEJB</remote>
	</ejb-ref>
<web-app>

Source code for weblogic.xml

Required when deploying to WebLogic.

Sample code:

<!DOCTYPE weblogic-web-app PUBLIC
 '-//BEA Systems, Inc.//DTD Web Application 8.1//EN'
 'http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd'>

<weblogic-web-app>
	<description>Stateful Ejb Sample</description>
	<reference-descriptor>
		<ejb-reference-description>
			<ejb-ref-name>ejb/AccountQueryStatefulEJB</ejb-ref-name>
			<jndi-name>AccountQueryStatefulEJB</jndi-name>
		</ejb-reference-description>
	</reference-descriptor>
	<session-descriptor>
		<session-param>
			<param-name>URLRewritingEnabled</param-name>
			<param-value>true</param-value>
		</session-param>
		<session-param>
			<param-name>IDLength</param-name>
			<param-value>52</param-value>
		</session-param>
		<session-param>
			<param-name>CookieComment</param-name>
			<param-value>WebLogic Server Session Tracking Cookie</param-value>
		</session-param>
		<session-param>
			<param-name>CookieMaxAgeSecs</param-name>
			<param-value>-1</param-value>
		</session-param>
		<session-param>
			<param-name>CookieName</param-name>
			<param-value>JSESSIONID</param-value>
		</session-param>
		<session-param>
			<param-name>InvalidationIntervalSecs</param-name>
			<param-value>60</param-value>
		</session-param>
		<session-param>
			<param-name>JDBCConnectionTimeoutSecs</param-name>
			<param-value>120</param-value>
		</session-param>
		<session-param>
			<param-name>PersistentStoreCookieName</param-name>
			<param-value>WLCOOKIE</param-value>
		</session-param>
		<session-param>
			<param-name>PersistentStoreDir</param-name>
			<param-value>session_db</param-value>
		</session-param>
		<session-param>
			<param-name>PersistentStoreType</param-name>
			<param-value>memory</param-value>
		</session-param>
		<session-param>
			<param-name>PersistentStoreTable</param-name>
			<param-value>wl_servlet_sessions</param-value>
		</session-param>
		<session-param>
			<param-name>CookiesEnabled</param-name>
			<param-value>true</param-value>
		</session-param>
		<session-param>
			<param-name>TrackingEnabled</param-name>
			<param-value>true</param-value>
		</session-param>
		<session-param>
			<param-name>TimeoutSecs</param-name>
			<param-value>3600</param-value>
		</session-param>
	</session-descriptor>
	<context-root>/StatefulEjbSample</context-root>
</weblogic-web-app>

Source code for orion-web.xml

Required when deploying to Oracle.

Sample code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE orion-web-app PUBLIC "-//Evermind//DTD Orion Web
Application 2.3//EN" "http://xmlns.oracle.com/ias/dtds/orion-web.dtd"
> <orion-web-app> <resource-ref-mapping location="AccountQueryStatefulEJB" name="eis/AccountQueryStatefulEJB"/> </orion-web-app>

The AccountQueryStatefulEJBClient.jar file

Application server

Description

WebLogic After the J2EE session EJB is packaged the client jar file is available to be downloaded.
SunOne After the J2EE session EJB has been deployed the client jar file is available to be downloaded.
WebSphere The client jar file is not required inside the WAR. It is created during the WebSphere deployment process.
Oracle The client jar file is not required because the WAR and EJB are inside the same application.
Related Topics
Bullet Using Tasks in Your Applications, Overview
Bullet How to Create and Deploy J2EE Session EJBs
  Attachmate