|
| Home > Apache Geronimo v3.0 > Documentation > Developing > Tutorials > Developing EJB applications > Stateful Session Bean |
This application will take you through the basics of Stateful Session Bean. This application will demonstrate how annotations like @Stateful, @Resource, @PostConstruct, @PreDestroy, @PrePassivate, @PostActivate, @Remove are used in an EJB3 application.
Basically a Stateful Session EJB is used whenever there is a requirement to maintain a session. The example is a user registration process wherein the registration process is a two step process. First page prompts to enter your personal credentials and second page prompts to enter your billing and credit card information. The session is maintained till the user has filled up both the jsp pages. Later the complete information is populated on to a database. The application has a Controller servlet which routes the call received from the jsp client to the Bean class, setter methods and jsp pages.
To run this tutorial, as a minimum you will be required to have installed the following prerequisite software.
Details on installing eclipse are provided in the Development environment section.
This tutorial is organized in the following sections:
This section is organized in the following parts:







package ejb.stateful; public class PersonalInfo implements java.io.Serializable { private static final long serialVersionUID = 1L; private String FirstName; private String LastName; private String UserName; private String Password; private String Nationality; public void setFirstName(String FirstName) { this.FirstName=FirstName; } public void setLastName(String LastName) { this.LastName=LastName; } public void setUserName(String UserName) { this.UserName=UserName; } public void setPassword(String Password) { this.Password=Password; } public void setNationality(String Nationality) { this.Nationality=Nationality; } public String getFirstName() { return FirstName; } public String getLastName() { return LastName; } public String getUserName() { return UserName; } public String getPassword() { return Password; } public String getNationality() { return Nationality; } }
package ejb.stateful; public class BillingInfo implements java.io.Serializable { private static final long serialVersionUID = 1L; private String houseNo; private String street; private String city; private String pincode; private String country; private String bank; private String cardno; public void setBank(String bank) { this.bank=bank; } public void setCardno(String cardno) { this.cardno=cardno; } public void setHouseNo(String houseNo) { this.houseNo=houseNo; } public void setStreet(String street) { this.street=street; } public void setCity(String city) { this.city=city; } public void setPincode(String pincode) { this.pincode=pincode; } public void setCountry(String country) { this.country=country; } public String getBank() { return bank; } public String getCardno() { return cardno; } public String getHouseNo() { return houseNo; } public String getStreet() { return street; } public String getCity() { return city; } public String getPincode() { return pincode; } public String getCountry() { return country; } }
PersonalInfo.java and BillingInfo.java are classes for setting and getting the user information.


package ejb.stateful; import javax.ejb.Remote; @Remote public interface AccountCreator { void addPersonalInfo(PersonalInfo personalinfo); void addBillingInfo(BillingInfo billinginfo); void createAccount(); }
Note: Once you enter this code you might see errors like @EJB can be resolved. Currently there are some limitations with the geronimo eclipse plugin which will resolved soon. We will soon suggest you how to get rid of those errors.


package ejb.stateful; import java.sql.Connection; import java.sql.Statement; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.ejb.PostActivate; import javax.ejb.PrePassivate; import javax.ejb.Remove; import javax.ejb.Stateful; import javax.sql.DataSource; @Stateful public class AccountCreatorBean implements AccountCreator{ @Resource(name="jdbc/userds") private DataSource datasource; private Connection connection; private PersonalInfo personalinfo=new PersonalInfo(); private BillingInfo billinginfo=new BillingInfo(); public AccountCreatorBean() { super(); } @PostConstruct @PostActivate public void openConnection() { try{ connection=datasource.getConnection(); } catch(Exception e) { e.printStackTrace(); } } @PreDestroy @PrePassivate public void closeConnection() { connection=null; } public void addPersonalInfo(PersonalInfo personalinfo) { this.personalinfo=personalinfo; } public void addBillingInfo(BillingInfo billinginfo) { this.billinginfo=billinginfo; } @Remove public void createAccount() { try{ System.out.println(personalinfo.getFirstName()); Statement statement = connection.createStatement(); String sql = "INSERT INTO USERINFO(" + "FIRSTNAME, " + "LASTNAME, " + "USERNAME," + "PASSWORD, " + " PINCODE, " + " CARDNO ) VALUES (" + "'" + personalinfo.getFirstName() + "', " + "'" + personalinfo.getLastName() + "', " + "'" + personalinfo.getUserName() + "', "+ "'" + personalinfo.getPassword() + "', "+ "'" + billinginfo.getPincode() + "', "+ "'" + billinginfo.getCardno() + "'" + ")"; statement.execute(sql); statement.close(); } catch(Exception e) { e.printStackTrace(); } } }
Once you have added the code you will see lot of errors but this can be resolved easily and is shown in next step. The errors in the code is due to missing classes from our server runtime.
Resolve the errors as follows.





Let us walk through the EJB bean class code.





create table userinfo(firstname varchar(20),lastname varchar(20), username varchar(20), password varchar(20), pincode varchar(20), cardno varchar(20))























package ejb.stateful; import java.io.IOException; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class for Servlet: Controller * */ public class Controller extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { static final long serialVersionUID = 1L; AccountCreator ac; /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */ public Controller() { super(); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*PrintWriter out =response.getWriter(); out.println(request.getRequestURI());*/ try{ Properties prop=new Properties(); prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory"); prop.put("java.naming.provider.url", "ejbd://localhost:4201"); Context context = new InitialContext(prop); ac=(AccountCreator)context.lookup("AccountCreatorBeanRemote"); } catch(Exception e) { e.printStackTrace(); } if ( (request.getRequestURI()).equals("/StatefulClient/Controller")) { PersonalInfo personalinfo=new PersonalInfo(); personalinfo.setFirstName(request.getParameter("FirstName")); personalinfo.setLastName(request.getParameter("LastName")); personalinfo.setNationality(request.getParameter("Nationality")); personalinfo.setUserName(request.getParameter("UserName")); personalinfo.setPassword(request.getParameter("Password")); ac.addPersonalInfo(personalinfo); HttpSession hs= request.getSession(true); hs.setAttribute("handle", ac); RequestDispatcher rd=request.getRequestDispatcher("BillingInfo.jsp"); rd.forward(request, response); } else { BillingInfo billingInfo=new BillingInfo(); billingInfo.setBank(request.getParameter("Bank")); billingInfo.setCardno(request.getParameter("CardNo")); billingInfo.setCity(request.getParameter("City")); billingInfo.setCountry(request.getParameter("Country")); billingInfo.setHouseNo(request.getParameter("HouseNo")); billingInfo.setPincode(request.getParameter("PinCode")); billingInfo.setStreet(request.getParameter("Street")); HttpSession hs= request.getSession(true); ac=(AccountCreator)hs.getAttribute("handle"); ac.addBillingInfo(billingInfo); ac.createAccount(); PrintWriter out=response.getWriter(); out.println("Account successfully created"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doProcess(request, response); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doProcess(request, response); // TODO Auto-generated method stub } }
This servlet contains code referring to bean interface class and PersonalInfo and BilllingInfo class. We need to add these projects to the build path so that the classes can be compiled.






<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>User Personal Information</title> </head> <body> <form action="Controller"> <h1>Enter your personal information</h1> <table> <tr> <td><h3>Name</h3></td> </tr> <tr> <td>FirstName</td> <td><input type="text" name="FirstName"></td> </tr> <tr> <td>LastName</td> <td><input type="text" name="LastName"></td> </tr> <tr><td><h3>Nationality</h3></td></tr> <tr> <td>Nationality</td> <td><input type="text" name="Nationality"></td> </tr> <tr><td><h3>Login</h3></td></tr> <tr> <td>UserName</td> <td><input type="text" name="UserName"></td> </tr> <tr> <td>Password</td> <td><input type="password" name="Password"></td> </tr> </table> <input type="submit" Name="Next"> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>User Billing Information</title> </head> <body> <form action="Controller1"> <h1>Enter your Billing information</h1> <table> <tr> <td><h3>Address</h3></td> </tr> <tr> <td>House No</td> <td><input type="text" name="HouseNo"></td> </tr> <tr> <td>Street</td> <td><input type="text" name="Street"></td> </tr> <tr> <td>City</td> <td><input type="text" name="City"></td> </tr> <tr> <td>PinCode</td> <td><input type="text" name="PinCode"></td> </tr> <tr> <td>Country</td> <td><input type="text" name="Country"></td> </tr> <tr><td><h3>Credit Card Information</h3></td></tr> <tr> <td>Bank</td> <td><input type="text" name="Bank"></td> </tr> <tr> <td>Card No</td> <td><input type="text" name="CardNo"></td> </tr> </table> <input type="submit" name="Submit"> </form> </body> </html>
Let's walk through the servlet and jsp code. First through Controller servlet code.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.2" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.2" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2"> <environment> <moduleId> <groupId>default</groupId> <artifactId>StatefulBean</artifactId> <version>1.0</version> <type>car</type> </moduleId> <sys:dependencies> <sys:dependency> <sys:groupId>console.dbpool</sys:groupId> <sys:artifactId>jdbc/userds</sys:artifactId> </sys:dependency> </sys:dependencies> </environment> </openejb-jar>
The above deployment plan is different from the above one in the following way
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>StatefulClient</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <description></description> <display-name>Controller</display-name> <servlet-name>Controller</servlet-name> <servlet-class>ejb.stateful.Controller</servlet-class> </servlet> <servlet> <description></description> <display-name>Controller1</display-name> <servlet-name>Controller1</servlet-name> <servlet-class>ejb.stateful.Controller</servlet-class> </servlet> <servlet-mapping> <servlet-name>Controller</servlet-name> <url-pattern>/Controller</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Controller1</servlet-name> <url-pattern>/Controller1</url-pattern> </servlet-mapping> </web-app>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns8:web-app xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ns2="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:ns3="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:ns4="http://geronimo.apache.org/xml/ns/j2ee/ejb/openejb-2.0" xmlns:ns5="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:ns6="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:ns7="http://java.sun.com/xml/ns/persistence" xmlns:ns8="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1" xmlns:ns9="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0"> <environment> <moduleId> <groupId>default</groupId> <artifactId>StatefulClient</artifactId> <version>1.0</version> <type>car</type> </moduleId> <dependencies> <dependency> <groupId>default</groupId> <artifactId>StatefulBean</artifactId> <version>1.0</version> <type>car</type> </dependency> </dependencies> </environment> <ns8:context-root>/StatefulClient</ns8:context-root> </ns8:web-app>
The above code is different from the original one in the sense that we have added another <servlet> for Controller1 which is mapped to the same servlet class. Similarly adding a <servlet-mapping> element for the Controller1 servlet. This feature is basically mapping of more than one servlet with same servlet class. This helps in routing each call from jsp in the Controller servlet.







|
|
Privacy Policy - Copyright © 2003-2013, The Apache Software Foundation, Licensed under ASL 2.0. |