为Stateless和有状态会话bean获取相同的输出

时间:2012-11-22 04:07:32

标签: ejb ejb-2.x

以下是我试过的示例代码

  <%@ 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>Sample1</title>  
</head>  
<body>  
<form action="ActionServlet" method="post">  
<h1>This is inside sample1</h1>  
<input type="submit">  
</form>  
</body>  
</html> 

发布于2012年11月19日星期一10:58:11 PM私信 引用 这是我尝试的示例代码

<%@ 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>Sample1</title>  
</head>  
<body>  
<form action="ActionServlet" method="post">  
<h1>This is inside sample1</h1>  
<input type="submit">  
</form>  
</body>  
</html>  

on单击“提交”,控件将导航到名为ActionServlet的servlet

 public class ActionServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    /** 
     * Default constructor.  
     */  
    public ActionServlet() {  
        // TODO Auto-generated constructor stub  
    }  

    /** 
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        // TODO Auto-generated method stub  
        doPost(request, response);  
    }  

    /** 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        // TODO Auto-generated method stub  
        System.out.println("This is inside doPost method for action servlet");  

        System.out.println("Before calling EJB for action servlet");  
        try{  
            Context ic = new InitialContext();  

            //first instance creation  
            StateFulServiceHome home=(StateFulServiceHome)ic.lookup("Stateful1234");  
            StateFulService sample=(StateFulService)home.create();  
            sample.setName("Hello1223");  
            sample.getName();  
            //second instance creation  
            Context ic1 = new InitialContext();  
            StateFulServiceHome home1=(StateFulServiceHome)ic1.lookup("Stateful1234");  
            StateFulService sample1=(StateFulService)home1.create();  
            sample1.getName();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("After calling EJB in action servlet1");  
        request.getRequestDispatcher("Sample2.jsp").forward(request,response);  

    }  

}  

ActionServlet在名为有状态会话bean的bean上调用业务方法

public class StateFulBean implements SessionBean{  
    String name;  
    public void setName(String name)throws RemoteException{  
        this.name =name;  
    }  
    private SessionContext context;  
    public void ejbActivate() throws EJBException, RemoteException {  
        // TODO Auto-generated method stub  
        System.out.println("*********This is inside ejbActivate method***********");  

    }  

    public void ejbPassivate() throws EJBException, RemoteException {  
        // TODO Auto-generated method stub  
        System.out.println("*********This is inside ejbpassivate method***********");  

    }  

    public void ejbRemove() throws EJBException, RemoteException {  
        // TODO Auto-generated method stub  
        System.out.println("*********This is inside Ejb remove method***********");  

    }  
    public void ejbCreate() throws EJBException,RemoteException{  
        System.out.println("*********This is inside create method***********");  
    }  
    public void setSessionContext(SessionContext ctx) throws EJBException,  
            RemoteException {  
        // TODO Auto-generated method stub  
        context=ctx;  
        System.out.println("*********This is for set session context***********");  
    }  
    public void getName()throws RemoteException{  
        System.out.println("***********This is for start of getting business method*****");  
        System.out.println("The name obtained is"+this.name);  
        System.out.println("***********This is for end of getting business method*****");  
    }  

} 

    public interface StateFulService extends EJBObject {  
    public void getName()throws RemoteException;  
    public void setName(String name)throws RemoteException;  
} 



  public interface StateFulServiceHome extends EJBHome {  
    public StateFulService create() throws RemoteException,CreateException;  
}  

最后是我的ejb-jar.xml

 <?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">  
<ejb-jar>  
 <enterprise-beans>  
   <session>  
      <ejb-name>Stateful1234</ejb-name>  
      <home>StateFulServiceHome</home>  
      <remote>StateFulService</remote>  
      <ejb-class>StateFulBean</ejb-class>  
      <session-type>Stateful</session-type>  
      <transaction-type>Container</transaction-type>  
   </session>  
</enterprise-beans>  
</ejb-jar>  

我为有状态和无状态会话bean获取相同的输出,我的假设是当我的bean被定义为有状态时,我应该在第二次查找bean时得到名称。

如果我错了,请告诉我。

-Shyam

1 个答案:

答案 0 :(得分:0)

  

我的假设是当我的bean被定义为有状态时,我应该在第二次查找bean时得到名称。

这不是有状态会话bean的工作方式。当您使用有状态会话bean时,您可以将代理存储到bean“某处”,即,当您在一段时间内未调用其上的方法时,容器将对其进行钝化。如果在销毁bean之前的任何时间通过代理发出后续请求,容器将“记住”客户端(在您的情况下为servlet)。换句话说,后续调用将记住会话状态,从而记住会话bean的有状态性质。您可以在会话bean中存储状态,甚至跨HTTP请求(因此,存储对代理的引用的原因)。

请注意,这与查找几乎没有关系。在您的代码中:

//first instance creation  
StateFulServiceHome home=(StateFulServiceHome)ic.lookup("Stateful1234");  
StateFulService sample=(StateFulService)home.create();  
sample.setName("Hello1223");  
sample.getName();  
//second instance creation  
Context ic1 = new InitialContext();  
StateFulServiceHome home1=(StateFulServiceHome)ic1.lookup("Stateful1234");  
StateFulService sample1=(StateFulService)home1.create();  
sample1.getName();

你已经创建了会话bean的两个实例,并且你有两个代理。第二个bean显然不会知道存储在第一个bean中的状态。

要考虑无状态会话bean,您需要记住存储对其代理的引用有点无意义,尤其是在HttpSession对象中。这主要是因为存储在bean中的状态仅在方法调用期间有效。 EJB容器管理无状态会话bean池,每次调用都可能涉及池中不同的未使用实例。

PS - 你现在学习EJB 2.x有什么理由吗?它不仅旧,Java EE 6应用程序中不再需要它的一部分,而且Java EE 7中正在修剪某些部分(实体bean)。