2012-03-16 3 views
3

배경 : MyFaces를 사용하는 JSF 2.0 응용 프로그램이 있습니다. 이 애플리케이션을 사용하여 사용자는 다양한 JSF 페이지를 통해 복잡한 "위젯"을 생성합니다. 세션 범위에 관리 빈을 저장하고 사용자가 각 페이지를 통과 할 때 속성이 채워집니다. 일단 그들이 "위젯"을 조립하면, 그들은 새로운 "위젯"을 만들고 그 과정을 반복하기를 원할 것입니다. 내 질문은 JSF 라이프 사이클을 중단시키지 않고 세션에서 관리 빈을 완전히 (안전하게) 제거하는 방법이다.JSF 2.0에서 Session Scoped Bean을 제거하는 방법 (언제?)

비슷한 질문에 대해 다른 응답을 보았을 때 세션을 무효화 할 수 있으며 FacesContext를 통해 HttpSession에 액세스하고 그 방법으로 Bean을 제거 할 수 있습니다. 사용자가 로그 아웃하거나 다시 로그인하면 안되며 전체 세션을 무효로하고 싶지 않습니다. FacesContext를 통해 HttpSession에 액세스하고 Bean을 제거해야한다고 가정하면 JSF 라이프 사이클에서이 작업을 안전하게 수행하여 문제가 나머지주기를 따라 계단식으로 전달되지 않는 가장 적절한 장소는 언제입니까? 나는 사용자가 다음 "위젯"을 만드는 과정을 시작할 때 JSF가 새로운 세션 빈을 만드는 데 아무런 문제가 없음을 확인하고자한다.

또한 JSF에서 이것이 더 쉬운 이유가 무엇인지 궁금합니다. 의도 한 JSF 패턴에 따라 더 나은 다른 접근법이 있습니까? 관리 Bean은 완료되기 전에 여러 페이지와 뷰를 거치기 때문에 뷰 범위를 사용할 수 없습니다.

미리 감사드립니다.

답변

2

여러 마법사 단계를 조건부로 렌더링하는 단일 페이지를 만듭니다.

<h:panelGroup rendered="#{wizard.step == 1}"> 
    <ui:include src="/WEB-INF/wizard/step1.xhtml" /> 
</h:panelGroup> 
<h:panelGroup rendered="#{wizard.step == 2}"> 
    <ui:include src="/WEB-INF/wizard/step2.xhtml" /> 
</h:panelGroup> 
<h:panelGroup rendered="#{wizard.step == 3}"> 
    <ui:include src="/WEB-INF/wizard/step3.xhtml" /> 
</h:panelGroup> 

그냥 많은 번거 로움없이이 한 페이지에 @ViewScoped 관리 빈을 사용할 수있는이 방법. 구체적인 질문에 관련없는


, PrimeFaces 거의 정확히 같은 않는 <p:wizard> 구성 요소를 가지고있다. 유효성 검사와 같은 보편적 인 코드에서 벗어나기 위해 유용 할 수 있습니다.

+0

감사합니다 BalusC, 나는 이것이 지금 상황에서 효과가있을 것이라고 생각합니다. 더 복잡한 응용 프로그램에서는 이것이 더 문제가 될 수 있습니다. 세션 빈을 다루는 것은 정말 많은 번거 로움입니까? – tcprogrammer

+0

이것에 ViewScope Bean을 사용하게되었습니다. 감사! – tcprogrammer

0

아직 사용하지는 않았지만 CDI의 ConversationScope을 살펴볼 것입니다.

+0

지금은 전체 J2EE 컨테이너가 아닌 서블릿 컨테이너를 사용하고 있지만 나중에 고려해야 할 사항입니다. – tcprogrammer

+0

[용접 참조 구현] (http://docs.jboss.org/weld/reference/1.0.0/en-US/html/environments.html#d0e4910)을 통해 서블릿 컨테이너에 CDI를 추가 할 수 있습니다. – fischermatte

1

위젯 생성 데이터가 단일 빈으로 캡슐화 된 경우 사례가 단순화 될 수 있습니다. 내가

<f:metadata> 
    <f:event type="preRenderView" listener="#{widgetMaker.resetWidget}"/> 
</f:metadata> 

당신은 포인터를 취할 수 있으며, 그에 따라 적응 (첫 번째 위젯 생성 페이지에서)보기에서 resetWidget를 들어

@SessionScoped 
@ManagedBean 
public class WidgetMaker { 
    private Widget widget; 

    public void makeWidget(){ 
    //after creating/saving widget 
    widget = new Widget(); 
    } 

    public void resetWidget(){ 
    //this method can be called with pre render view handler 
    //call this method on the first page that starts widget creation 
    //in case person leaves the widget creation in between and starts over again 
    widget = new Widget(); 
    } 
} 

을 의미한다.

희망이 도움이됩니다.

+0

최종 사용자가 새 브라우저 탭에서 다중 단계 프로세스의 중간 단계에서 widget 페이지를 열면 어떻게됩니까? 분명히 그 두 개의 탭/창은 서로를 방해 할 것입니다. – BalusC

+0

@BalusC는 설명대로 답했습니다. 그 함정은 분명했습니다. 동의했습니다. –

+0

제 경우 엔 요청 범위에 컨트롤러/백킹 빈이 있으며, EntityManager 작업과 같이 스레드로부터 안전하지 않은 것들을 수행합니다. 세션 빈이 세션 빈에 삽입됩니다. 이 디자인을 사용하면 preRenderView가 세션 빈을 제거하는 메소드를 실행하기에 안전한 장소가 될까요? – tcprogrammer

0

본인은 BalusC에 동의합니다. 귀하의 경우 뷰 범위가 더 나은 선택이 될 것입니다. 방금 세션 범위에서 다중 페이지 형식을 가진 JSF 프로젝트를 살펴 보았습니다. 나중에 나는 잘 알려진 이유로 국가를보기로 전환했다.beanName

MyBean newInstance = new MyBean(); 
FacesContext.getCurrentInstance().getExternalContext() 
    .getSessionMap().put(beanName, newInstance); 

을 빈의 엘 이름 (문자열)로 :

그러나, 나는 세션이 단순히 세션 맵 인스턴스를 교체하여 콩을 범위 재설정했다.

+0

필자가 게시물에서 언급했듯이 세션 맵에서 Bean에 액세스하는 방법을 알고 있었지만 JSF 라이프 사이클의 어느 부분에서이 작업을 안전하게 수행 할 수 있었습니까? – tcprogrammer

+0

명령 단추 작업 메서드에서 올바른 단계인지 여부를 신경 쓰지 않았습니다. –

관련 문제