In order to illustrate the creation of a stateful EJB, we will use a bean to maintain a list of names. A name will be entered in the index.jsp
page and passed to a servlet. The servlet will add the name to the stateful bean. Unique to the stateful EJB is the process of passivation. When a stateful bean is experiencing a period of inactivity, the EJB container may decide to remove it from memory temporarily. This process is called passivation. Most of the state of the EJB is saved automatically except for transient fields. When the EJB is restored, the stateless EJB has its original content except for the transient fields.
Creating a stateful session bean requires:
Earlier versions of EJB required the use of local and/or remote interfaces. This is no longer necessary.
To use a session bean, inject the EJB into the client using the @EJB annotation followed by the declaration of the bean. In this recipe, we will use a servlet to demonstrate this process. Remember, it is important to use the @EJB annotation, otherwise the bean will not be managed by the EJB container and it will not be able to take advantage of the support provided to EJBs.
Let's start by creating a Java EE application called StatefulExample
. Add a package called packt
and a stateful EJB called NamesBean
to the EJB module. Also, add a package called servlet
and a servlet called NamesServlet
to the WAR module.
The NamesBean
EJB maintains a list of names. Two methods are used. The addName
method adds a name to the list and the getNames
method returns a list of names.
@Stateful @LocalBean public class NamesBean { private List<String> names; @PostConstruct private void initialize() { names = new ArrayList<String>(); } public void addName(String name) { names.add(name); } public List<String> getNames() { return names; } }
The NamesServlet
injects the NamesBean
and uses it to add names passed to it.
public class NamesServlet extends HttpServlet { @EJB private NamesBean names; private List<String> list; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { names.addName(request.getParameter("name")); list = names.getNames(); out.println("<html>"); out.println("<head>"); out.println("<title>NamesServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h3>Current List of Names</h3>"); for(String name: list) { out.println(name + "<br>"); } out.println("</body>"); out.println("</html>"); } finally { System.out.println("Error"); out.close(); } } }
A simple implementation of the index.jsp
pages prompts the user for a name and passes the name to the NamesServlet
.
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>Stateful EJB Example</title> </head> <body> <h1>Names Example</h1> <form action="NamesServlet" method="get"> Name: <input type="text" name="name" /><br /> <input type="submit" value="Add Name" /> </form> </body> </html>
Start the application using the URL provided in the following screenshot. Enter a name and press the Add Name button:
When the index.jsp
page is executed repeatedly, names are added to the list and the NamesServlet
page displays a list similar to the one shown in the following screenshot:
The NamesBean
class used an ArrayList
to maintain a list of names. A method was provided to add a name and to return a List
of the names. The addName
method used the add
method of the List
to add a name. The getNames
method returned this ArrayList
. Notice that names
is a reference to an object that implements the List interface. However, an ArrayList
object was actually assigned. By using the more generic List
interface, in the future if we change our implementation, calling methods are not affected.
In the NamesServlet
, the getParameter
method returned a value associated with the parameter name
. Notice this name was declared in the input
tag of the index.jsp
file. The value entered by the user was passed to the servlet using this parameter.
When the stateful EJB is passivated, it is sometimes necessary for the EJB to perform additional actions. For example, certain resources, such as database connections may need to be closed. Likewise, when the EJB is restored the resources may need to be restored. The @PrePassivate and @PostActivate methods are used to designate which methods need to be executed when passivation or restoration occurs.
@PrePassivate private void prepareForPassivation() { // Perform prepassivation tasks } @PostActivate private void restoreFromPassivation() { // Restore stateful EJB }
18.218.151.44