2012-04-26 33 views
1

我對EJB很新穎。我需要有狀態的bean在我的EAR應用程序中。我有一個EJB模塊中創建簡單的有狀態會話bean:有狀態EJB的問題 - 爲所有用戶保留一個會話

@Stateful 
public class Test { 

    public Test() { 
    } 

    private int i; 

    @PostConstruct 
    public void initialize() { 
     i = 0; 
    } 

    public int getI() { 
     return i++; 
    } 
} 

而且我在戰爭中模塊調用它的servlet:

public class TestServlet extends HttpServlet { 

    @EJB 
    Test test; 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     PrintWriter out = response.getWriter(); 

     HttpSession session = request.getSession(true); 

     out.println("<html>"); 
     out.println("<head>"); 
     out.println("<title></title>");    
     out.println("</head>"); 
     out.println("<body>"); 
     out.println("<h1>" + test.getI() + "</h1>"); 
     out.println("</body>"); 
     out.println("</html>");   
     out.close(); 
    } 
... 
} 

當我運行它,數量越大隨着每次刷新一個瀏覽器。

0,1,2,...

但是,當我在其他瀏覽器中運行,該數字不從0開始,但繼續從以前的瀏覽器會話。它表現得像單身人士。

3,4,5,...

爲什麼沒有bean的一個新的實例創建?我嘗試將會話bean放入war模塊中,或者使用SessionScoped對其進行註釋,但結果相同。

你能幫我爲每個http會話創建一個有狀態bean的新實例嗎?

回答

4

創建單個servlet來爲所有請求提供服務。您將一個有狀態會話bean的實例注入到servlet中,因此所有請求都將使用同一個有狀態會話bean。注入有狀態的會話bean是很有用的。

您需要創建有狀態會話bean的每個實例的HttpSession:

// Declare the reference without injection... 
@EJB(name="ejb/test" beanInterface=Test.class) 
public class TestServlet extends HttpServlet { 
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     PrintWriter out = response.getWriter(); 

     HttpSession session = request.getSession(true); 
     Test bean = session.getAttribute(BEAN); 
     if (bean == null) { 
      try { 
       // ...and then create an instance by looking it up from java:comp/env 
       bean = (Test)new InitialContext().lookup("java:comp/env/ejb/test"); 
      } catch (NamingException ex) { ... } 
      session.setAttribute(BEAN, bean); 
     } 

     ... 
    } 
} 

或者,如果你有CDI,你可以標記您有狀態會話bean作爲@SessionScoped和使用@Inject注射而比@EJB。

+1

謝謝你的回答。我嘗試了SessionScoped,但它沒有工作。我的錯誤是我使用EJB獲取實例,但應該使用Inject。所以現在我很高興地使用SessionScoped Stateful和Inject注入,它的工作原理。 – ziri 2012-04-26 16:04:14

+0

啊,是的,我忘了提@Inject。更新了答案,謝謝。 – 2012-04-26 23:33:01