Download Lecture 7: Introduction to EJB

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CPAN423 Enterprise Java Programming
Lecture #7: Introduction to EJB-Session Beans
Enterprise Java Beans is one of the Java-based distributed component
technologies for building business logic in enterprise solutions. EJB applications
run in a multithreaded environment where the EJB component(s) implements the
business logic. EJB components execute within an EJB container, which is
managed by an application server. EJB applications can be distributed across
many tiers, but the 3 tiers architecture is most widely used. The 3 tiers
architecture consists of the layers: presentation, business logic, and
database.
In the client tier the application client container runs and manages the client
application. In the middle tier the web container manage JSP and servlets and
the EJB container manages the execution and life cycle of all the EJB on the
server. The web and EJB containers provide all the required system level
services such as transaction management, state management, security,
database pooling, performance and concurrency. Since the client in the
presentation tier focuses on implementing the presentation logic and use EJB for
business methods, it is called thin client.
The following diagram shows the architecture of 3 tiers enterprise Java beans
application:
browser
Application
Client
Application
Client
Container
JSP and
Servlet
Web Container
EJBs
EJB Container
Client Machine
Server Machine
Database Server
machine
1
There are three types of EJB: Session, Entity, and Message Driven. This
lecture focuses on Session beans. Entity and Message Driven are covered in
the next lectures
An instance of a session beans handles business logic methods for one or more
clients. Session beans are not persistent, which means that session EJB do not
store their data into a database. If the Server crashes, all session EJB instance
are lost including their data. However. Session beans may maintain status during
an interactive session with the client.
There are two types of session beans:

Stateful: An instance of stateful session beans stores data for a particular
client and maintain state during the client calls to methods of this bean.
The EJB container creates new stateful session bean instance for each
client. The stateful session bean has three states: Do not exist, Ready
and Passive. The stateful session bean transition to Ready state after the
container creates an instance of this bean. The container does that by
calling the methods Class.newInstance, setSessionContext and
ejbCreate in sequence. This bean transit to Do not exist state when the
client terminates the session. The container does that by calling
ejbRemove method. The container also transitions the stateful session
bean to a passive state to free some memory resources by moving the
bean from the memory to the secondary storage by calling ejbPassivate
method. If a client calls a method of a passive stateful session bean, the
container transition the bean to Ready state by calling ejbActivate
method.

Stateless: An instance of a stateless session bean does not store data
that are specific to a particular client. The EJB container creates a pool of
instances from the same stateless session bean. Any available instance
can be assigned for a client request. The EJB container makes this
instance available after the client finishes calling the bean’s methods. The
stateless session bean has two states: Do not exist, and Ready. The
stateless session transition to Ready state after the container creates an
instance of this bean. The container does that by calling the methods
Class.newInstance, setSessionContext and ejbCreate in sequence.
This bean transition to Do not exist state when there is no more requests
for its instance. The container does that by calling ejbRemove method.
Stateless session exhibit high performance and is scalable for large
number of clients.
The client of a session bean invokes business methods of the bean through a
bean interface. Two types of interfaces are possible with session bean (also
with an entity bean):
 Home and Remote Interfaces: Enables clients to access a bean
remotely. The remote interface defines the business methods of the
bean. The Home interface defines the life cycle methods of the bean.
2

Remote client can be JSP, servlet, J2EE application client , or another
EJB.
Local Home and Local Interfaces: Enables clients to access a bean
locally. The Local interface defines the business methods of the bean.
The Local Home interface defines the life cycle methods of the bean.
Local client can be JSP, servlet, another EJB, but not a J2EE
application client.
The EJB implementation class provides implementation for the bean’s
business and life cycle methods. The EJB container provides an environment
for running EJB and manages the life cycle of the EJB. The EJB container is
included within an application server that provides system level services.
To perform a certain business transaction, business methods must be called
in a specific sequence. The transaction is committed if all the required steps
are executed properly and rolled back if any step is not executed properly.
The boundary of the transaction (start and end) is called transaction
demarcation. J2EE supports two methods for managing transactions:
programmatic (bean-managed transaction demarcation ) and declarative
(container-managed transaction demarcation). The EJB developer can
either write the code to managed transaction demarcation manually, or use
declarative in the EJB deployment descriptor to specify the method(s) that
requires container-managed transaction and their attributes. Session beans
support the two methods of transaction management. The textbook provides
some transaction management examples with session beans on pages 879890.
Examples:
Ex1: Stateless Session Bean example with a servlet as a client:
This example creates a remote stateless session beans that checks a user login
and will e used by a servlet.. First we will write a remote interface called
PersonalInterface that has the following content:
package Login;
import java.rmi.*;
import javax.ejb.*;
public interface PersonalInterface extends EJBObject
{
boolean check(String name, String pass) throws RemoteException;
}
3
Then we will write a Home interface called PersonalInterafaceHome that has
the following content:
package Login;
import java.rmi.*;
import javax.ejb.*;
public interface PersonalInterfaceHome extends EJBHome
{
public PersonalInterface create() throws RemoteException,
CreateException;
}
Then we will provide a class called PersonalInterfaceBean that provide
implementation for the method check of the remote interface PersonalInterface.
This method will loop through two arrays of names and passwords to validate the
user login. The user login(name/password) should be passed as parameters to
check method. If a matching is found then check will return true, otherwise it will
return false. PersonalInterfacBean.java should have the following content:
package Login;
import java.rmi.*;
import javax.ejb.*;
public class PersonalInterfaceBean implements SessionBean
{
/*
define two arrays for users’ names and passwords
*/
private String [] userName={"a","b","c"};
private String [] userPassword={"1","2","3"};
public void ejbCreate() { }
public void setSessionContext(
SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public boolean check(String name, String pass)
{
boolean found=false;
for (int i=0;i<userName.length;i++)
if (userName[i].equals(name) && userPassword[i].equals(pass))
4
found=true;
return found;
}
}
The following is a Servlet called LoginServlet that obtain a remote reference to
the PersonalInterface object, and call check method to validate the user login.
import java.io.*;
import javax.ejb.*;
import javax.naming.*;
import javax.servlet.*;
import javax.rmi.PortableRemoteObject;
import javax.servlet.http.*;
import Login.*;
public class LoginServlet extends HttpServlet {
/**
* The servlet stores the home interface after the initial lookup.
* Since the home interface never changes, caching the lookup will save
* some performance.
*/
private PersonalInterfaceHome piHome=null;
/**
* The init method looks up the HelloHome interface using JNDI and
* stores it in a servlet variable.
*/
public void init() throws ServletException
{
try {
/*
* Look up the remote EJB context using JNDI.
* The context contains the remote EJB beans.
*/
Context ctx = new InitialContext();
piHome = (PersonalInterfaceHome)
ctx.lookup("java:comp/env/ejb/login");
5
}
catch (NamingException e)
{
throw new ServletException(e);
}
}
public void doPost (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String uName=req.getParameter("userName");
String uPassword=req.getParameter("userPassword");
try
{
PersonalInterface pi= piHome.create();
if (pi.check(uName,uPassword))
{
out.println("Login correct");
}
else
{
out.println("Login inccorrect <a
href='http://localhost:8080/SessionEJB/loginEJB.html'> try again </a>");
}
}
catch(Exception e)
{
out.print( e.toString());
}
}
}
6
And here is an HTML file called loginEJB.html that will be used to invoke the
LoginServlet:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Login Example</title>
</head>
<body>
<form method="post" action="http://localhost:8080/SessionEJB/login" >
Enter User Name: <input type="text" name="userName" size="20" /><br>
Enter User password: <input type="password" name="userPassword"
size="10" /><br>
<input type="submit" value="Login">
</form>
</html>
EJB applications are deployed under webapps folder of Resin web server. We
will deploy our EJB under a folder called SessionEJB. The following steps
illustrate the required steps:
 Create a folder called SessionEJB under webapps folder.
Any HTML or JSP file should be stored in SessionEJB folder.
 Under SessionEJB folder create a folder called WEB-INF. WEB-INF
contain the web application deployment descriptor files: web.xml and one
EJB descriptor file for each beans deployed under SessionEJB folder.
o Under WEB-INF create the following folders:
 classes: contains the servlet classes, the EJB classes and
any other supporting classes. We will package our EJB
classes into a folder called Login.
 lib: Contain any JAR file used in the web application. JARs
can contain EJB, servlets and other supporting classes.
The resulting structure should look as follow:
webapps
SessionEJB
WEB-INF
classes
Login
lib
7
The
files
PersonalInterface.java,
PersonalInterfaceHome.java
and
PersonalInterfaceBean.java should be stored under Login folder.
LoginServlet.java should be stored under classes folder. loginUser.html
should be stored under SessionEJB folder.
Following is an EJB descriptor file called login.ejb that should be stored under
WEB-INF folder:
<?xml version="1.0"?>
<ejb-jar xmlns="http://caucho.com/ns/resin">
<enterprise-beans>
<session>
<!-- The ejb-name is used for the JNDI lookup to find the home interface
-->
<ejb-name>login</ejb-name>
<!-- home defines the bean's remote home interface.
-->
<home>Login.PersonalInterfaceHome</home>
<!-- remote defines the bean's remote interface.
-->
<remote>Login.PersonalInterface</remote>
<!-- stateless session beans are like servlets without HttpSession.
-->
<!-- ejb-class defines the bean's implementation class.
-->
<ejb-class>Login.PersonalInterfaceBean</ejb-class>
<session-type>Stateless</session-type>
<!-- The container handle the transactions.
-->
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
Following is the web application deployment descriptor for this application
(web.xml) that should be stored under WEB-INF folder:
8
<web-app xmlns="http://caucho.com/ns/resin">
<!-- EJB Server configuration -->
<ejb-server config-directory="WEB-INF"/>
<servlet servlet-name='hessian' servletclass='com.caucho.hessian.EJBServlet'/>
<servlet-mapping url-pattern='/hessian/*' servlet-name='hessian'/>
<servlet servlet-name='count' servlet-class='CountServlet'/>
<servlet-mapping url-pattern='/count' servlet-name='count'/>
<!-- Configuration for the client.
- Normally, this would not be in the same web.xml as the server
- because the client and the server would be separate. For the
- purposes of this tutorial, both the client and the server are in the
- same web-app
-->
<!-- a alternative client servlet that uses JNDI -->
<servlet servlet-name='login' servlet-class='LoginServlet'/>
<servlet-mapping url-pattern='/login/*' servlet-name='login'/>
<jndi-link jndi-name='java:comp/env/ejb'
factory='com.caucho.hessian.HessianContextFactory'>
<init-param java.naming.provider.url='${app.url}/hessian'/>
</jndi-link>
</web-app>
The login form in this example can be invoked by typing the following in the
browser URL: http://localhost:8080/SessionEJB/loginEJB.html
Ex2: EJB stateless session bean example with JSP as a client
In this example we will build a JSP called login.jsp that will use the stateless
session bean defined in Ex1.
The procedure for compiling and running the
9
remote session bean is the same as in Ex1. The JSP page should be saved
under SessionEJB folder.
<%@ page import="Login.*, javax.ejb.*,
javax.naming.*,javax.rmi.PortableRemoteObject" %>
<%!
public PersonalInterfaceHome piHome;
// Get the home stub once and save it in home
public void jspInit()
{
super.jspInit();
try {
Context ctx = new InitialContext();
piHome = (PersonalInterfaceHome)
ctx.lookup("java:comp/env/ejb/login");
} catch (NamingException e)
{
e.printStackTrace();
}
}
%>
<%
try
{
PersonalInterface pi= piHome.create();
String uName=request.getParameter("userName");
String uPassword=request.getParameter("userPassword");
if (pi.check(uName,uPassword))
{
out.println("Login correct");
}
else
{
out.println("Login inccorrect <a
href='http://localhost:8080/SessionEJB/loginEJBJSP.html'> try again
</a>");
}
}
catch(Exception e)
{
out.print( e.toString());
}
10
%>
Below is an HTML form called loginEJBJSP.html that will invoke login.jsp:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Login Example</title>
</head>
<body>
<form method="post"
action="http://localhost:8080/SessionEJB/login.jsp">
Enter User Name: <input type="text" name="userName" size="20" /><br>
Enter User password: <input type="password" name="userPassword"
size="10" /><br>
<input type="submit" value="Login">
</form>
</html>
Both login.jsp and loginEJBJSP.html should be store under SessionEJB
folder.
loginEJBJSP.html can be invoked by typing the following in the browser URL:
http://localhost:8080/SessionEJB/loginEJBJSP.html
Ex3: EJB stateful session bean example with JSP as a client
This example creates a remote stateful session beans that counts the number of
hits and will e used by a JSP. First we will write a remote interface called
CountInterface that has the following content:
package counter;
import java.rmi.*;
import javax.ejb.*;
public interface CountInterface extends EJBObject {
int returnCount() throws RemoteException;
}
Then we will write a Home interface called CountInterafaceHome that has the
following content:
11
package counter;
import java.rmi.*;
import javax.ejb.*;
public interface CountInterfaceHome extends EJBHome {
public CountInterface create() throws RemoteException, CreateException;
}
Then we will provide a class called CountInterfaceBean that provide
implementation for the method returnCount of the remote interface
CountInterface. This method will increment the count variable each time it will
be called. count is called state variable.
package counter;
import java.rmi.*;
import javax.ejb.*;
public class CountInterfaceBean implements SessionBean
{
private int count;
public void ejbCreate() { }
public void setSessionContext(
SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public int returnCount()
{
return count++;
}
}
Below is a JSP file called count.jsp that will use this stateful session bean.
<%@ page import="counter.*, javax.ejb.*,
javax.naming.*,javax.rmi.PortableRemoteObject" %>
<%!
private CountInterfaceHome cntHome;
// Get the home stub once and save it in home
public void jspInit()
12
{
super.jspInit();
try {
Context ctx = new InitialContext();
cntHome = (CountInterfaceHome)
ctx.lookup("java:comp/env/ejb/count");
} catch (NamingException e) {
e.printStackTrace();
}
}
%>
<%
try
{
CountInterface cnt= cntHome.create();
out.println(cnt.returnCount()+"<br/>");
out.println(cnt.returnCount()+"<br/>");
}
catch(Exception e)
{
out.print( e.toString());
}
%>
The EJB descriptor for this bean is called count.ejb and should have the
following content:
<?xml version="1.0"?>
<ejb-jar xmlns="http://caucho.com/ns/resin">
<enterprise-beans>
<session>
<ejb-name>count</ejb-name>
<home>counter.CountInterfaceHome</home>
<remote>counter.CountInterface</remote>
13
<ejb-class>counter.CountInterfaceBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
The
files
CountInterface.java,
CountInterfaceHome.java
and
CountInterfaceBean.java should be stored under a folder called
webapps/SessionEJB/WEB-INF/classes/counter. count.jsp should be stored
under
SessionEJB
folder.
count.ejb
should
be
stored
under
webapps/SessionEJB/WEB-INF folder.
count.jsp can be invoked by typing the following in the browser URL:
http://localhost:8080/SessionEJB/count.jsp
14