2011-12-16 3 views
4

응용 프로그램 내에서 현재 사용자 정보를 유지하기 위해 사용할 상태 유지 EJB가 있습니다. 이 EJB는 서블릿 컨트롤러에 삽입되어 마지막으로 로그인 한 사용자를 저장하는 데 사용됩니다. 그러나 세션은 모든 단일 클라이언트에서 동일하게 보입니다.상태 유지 EJB 및 동일한 세션이 클라이언트간에 복제 됨

샘플 EJB 코드 :

Stateful 
@LocalBean 
public class CurrentUserBean { 

private string Username; 

public void setUser(String un) 
{ 
    Username = un; 
} 

.... 

샘플 서블릿 코드 : 응용 프로그램이 내 서버에 배포하고 내가 여러 클라이언트에서 서버와 통신 많은 다른 사람이되어 지금

public class MainController extends HttpServlet { 
     @EJB private CurrentUserBean userBean; 

     protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

       HttpSession session = request.getSession(); 
       String name = session.getAttribute("username"); 

       userBean.setUser(name); 
       ...... 

, , 사용자 이름은 항상 로그인 한 마지막 사용자로 설정됩니다. 즉, 상태있는 세션 bean이 모든 클라이언트에서 동일한 상태를 유지하고있는 것처럼 보입니다. 내가 247 페이지에서 자바 6 EE 튜토리얼에서 다음 견적을 읽을 때이 크게 나를 혼동 : 상태 유지 세션 빈에서

, 인스턴스 변수는 고유 한 클라이언트/콩 세션의 상태 를 나타냅니다. 클라이언트가 ("대화")을 해당 Bean과 상호 작용하기 때문에이 상태를 대화 형 상태라고 종종합니다. 이름에서 알 수 있듯이 세션 빈은 대화 형 세션과 유사합니다. 세션빈은 공유되지 않습니다. 대화 형 세션에는 한 명의 사용자 만 가질 수있는 동일한 방법으로 하나의 클라이언트 만 개만 가질 수 있습니다. 클라이언트가 종료되면 세션 빈은 으로 나타나며 더 이상 클라이언트와 연관되지 않습니다.

왜 이런 일이 발생하는지 설명하고 모든 클라이언트에서 동일한 상태를 유지하지 않는 적절한 방식으로 stateful beans를 사용하는 방법을 설명 할 수 있습니까?

감사합니다.

+0

당신이 너무 다른 HTTP 세션을 얻거나 동일합니까? – Thomas

+0

테스트 할 수있는 유일한 방법은 내가 다른 사람으로 로그인 한 상태에서 사용자가 전화를 걸어서 응용 프로그램을 건너 뛰고 로그온 한 것을 알았 기 때문입니다. 그 같은 사용자와 나는 심지어 아직 인증을하지 않았다. – JCab

답변

6

statefull 세션 빈은 사용자 당 상태 (실제로 세션)가 있지만 서블릿은 그렇지 않습니다. 이것을 주입함으로써 이제는 단일 서블릿이 서블릿이 생성 될 때 주입되기 때문에이 서블릿에 의해 사용된다. (아마도 첫 번째 방문객에게 보내지는 콩 일 것이다).

빈을 삽입하지 말고 processRequest 메소드 내의 컨텍스트에서 검색해야합니다.

InitialContext ctx= new InitialContext(); 
CurrentUserBean userBean = (CurrentUserBean)ctx.lookup("CurrentUserBean"); 
+2

+1. 하나의 서블릿 인스턴스 만 생성되고 모든 요청은 다른 스레드의 동일한 인스턴스에 의해 처리됩니다. 따라서 기본적으로 동일한 EJB 인스턴스가 모든 클라이언트에 의해 공유됩니다. –

1

아니면

@Inject 
Instance<CurrentUserBean> currentUserBeanInstance; 

protected void processRequest(... 
    CurrentUserBean currentUserBean = currentUserBeanInstance.get(); 

을 사용 만 자바 EE 6

+0

CDI가 필요합니다. –