2011-08-04 6 views
1

I 그 흐름이 생성되고, 사용자가 의도적 roomId 변경 후 경우 url로 입력 할 때 사용자가이스프링 webflow - 엔드 흐름 실행 스냅

http://webserver.com/someapp/test/test-flow?roomId=12345

같은 URL을 입력 보안 요구의 종류가 매개 변수 일부 보안 필터는 사용자가 해당 방에 대한 액세스 권한이 있는지 확인합니다. 액세스 권한이있는 경우 계속 진행할 수 있지만 그렇지 않으면 흐름을 종료해야하며 모든 흐름 스냅 샷을 제거하는 것이 좋습니다 (여러 개가있는 경우). 그래서 코드 필터로부터이

추출 같다 :

public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) throws IOException, ServletException { 
HttpServletRequest req = (HttpServletRequest) request; 
HttpServletResponse resp = (HttpServletResponse) response; 
String roomId = req.getParameter("roomId"); 
if (roomId != null) { 
    if (currentUserHasAccess(roomId)) { 
    chain.doFilter(request, response); 
    } else { 
    flowExecutionManager.endFlow(); 
    return; 
    } 
} 
chain.doFilter(request, response); 
} 

지금 flowExecutionManager 난 다음 행의 순서를 전환 시도한 endFlow 방법이

public class FlowExecutionManager extends FlowExecutionListenerAdapter { 
private RequestControlContext context; 
private FlowDefinition definition; 

@Override 
public void sessionCreating(RequestContext context, 
    FlowDefinition definition) { 
super.sessionCreating(context, definition); 
this.context = (RequestControlContext) context; 
this.definition = definition; 
} 

public void endFlow() { 
if (context != null && definition != null) { 
    context.removeAllFlowExecutionSnapshots(); 
    context.endActiveFlowSession(definition.getId(), definition.getAttributes()); 
    Flow flow = (Flow)definition; 
    flow.destroy(); 
} 
} 

같다

context.endActiveFlowSession(definition.getId(), definition.getAttributes()); 
context.removeAllFlowExecutionSnapshots(); 

그리고이 두 줄의 순서에 상관없이 나는 항상 이와 같은 NPE를 얻는다. (단지 extr 스택 트레이스의 행위)

java.lang.NullPointerException 
at org.springframework.webflow.conversation.impl.SessionBindingConversationManager.getConversationContainer(SessionBindingConversationManager.java:140) 
at org.springframework.webflow.conversation.impl.SessionBindingConversationManager.getConversation(SessionBindingConversationManager.java:116) 
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:183) 
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:170) 
at org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository.removeAllFlowExecutionSnapshots(DefaultFlowExecutionRepository.java:156) 
at org.springframework.webflow.engine.impl.FlowExecutionImpl.removeAllFlowExecutionSnapshots(FlowExecutionImpl.java:431) 
at org.springframework.webflow.engine.impl.RequestControlContextImpl.removeAllFlowExecutionSnapshots(RequestControlContextImpl.java:230) 
at com.ags.blackcorp.finances.web.FlowExecutionManager.endFlow(FlowExecutionManager.java:26) 
at com.ags.blackcorp.finances.web.RoomFilter.doFilter(RoomFilter.java:100) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) 
at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101) 
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91) 
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at com.ags.blackcorp.security.ui.webapp.AfterAuthenticationProcess.doFilterHttp(AfterAuthenticationProcess.java:55) 
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at org.springframework.security.ui.preauth.AbstractPreAuthenticatedProcessingFilter.doFilterHttp(AbstractPreAuthenticatedProcessingFilter.java:69) 
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235) 
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) 
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390) 
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) 

분명히 선 context.endActiveFlowSession(definition.getId(), definition.getAttributes());이 흐름을 종료한다하지만 난 실행 스냅 샷을 제거 기운 다. 내가 뭘 잘못하고 있는지, 또는 어떤 생각을 어떻게 실행 스냅 샷을 제거하는 모든 아이디어. 최상의 접근 방식에 대한 아이디어. 미리 감사드립니다. 내 자신의 질문에 대답하려고

+0

flowstart에서 flowId 변수에 roomId를 저장 한 다음 쿼리 매개 변수를 무시하는 이유는 무엇입니까? 그 후에? 그렇다면 사용자가 무엇을하는지 신경 쓰지 않아도됩니다. – Patrick

답변

0

은 다음 코드 조각를 알려준 :

public void endFlow() { 
if (context != null && definition != null) { 
    ExternalContextHolder.setExternalContext(contex.getExternalContext()); 
    context.removeAllFlowExecutionSnapshots(); 
    context.endActiveFlowSession(definition.getId(), definition.getAttributes()); 
    Flow flow = (Flow)definition; 
    flow.destroy(); 
    } 
} 

ExternalContextHolder는 ... 라인이 NPE를 방지하고, 스냅 샷은 제거하고 flowSession는 또한 종료, 그러나 새로운 질문이 있습니다 발생했습니다

  • 왜 ExternalContextHolder가 필요합니까? 괜찮 니?. 다음은

은 몇 가지 이상한 (또는 정상입니까?) 점점 행동 메신저 내가 '브라우저 TAB1의 흐름 e1s1을 시작하며 e2s1 다른 탭에서, 지금의 경우 메신저를 e2s1에 클릭 한 가정하자

다음 '버튼을 내 마법사에서 e2s2 (지금), e1s1에 속하는 실행 스냅 샷을 제거하면 문제없이 제거되지만 e2s2가있는 탭으로 이동하면'이전 '버튼을 클릭 할 수 있습니다. 이전 스냅 샷으로 돌아 가기, 스냅 샷 e2s1도 사라졌습니다. 즉, 스냅 샷 제거가 "실행 당"과 같아야한다는 의미입니다. FlowExecutionRepository 클래스의 removeFlowExecution 메서드를 사용하여 흐름 실행을 제거하는 새로운 코드를 테스트했지만 지금은 표시하지 않습니다. 대신 누군가가 포인터를 던질 수 있으면 기다려주십시오. 어쨌든 아무 것도 나타나지 않으면 아무도 루프에 관심을 갖지 못하게됩니다.

내 질문에 대한 답변을 다시 한 번 입력하면 희망적인 마지막 답변입니다.

Q : ExternalContextHolder가 필요한 이유는 무엇입니까?

Ans : 내 작은 경험에 따르면 ExternalContextHolder가 필요할 것이므로 Spring은 요청을 보낸 사람이 보낸 데이터에 액세스 (HttpServletRequest 및 HttpServletResponse) 할 수 있습니다.

마지막으로 필터에서 flowexecution을 제거하는 것이 좋은 생각 일지 모르지만 webflow를 사용하면 FlowExecutionListenerAdapter를 서브 클래 싱하는 것이 더 효율적입니다.이 경우에는 "void requestSubmitted (RequestContext context)"메소드를 오버로드하고 여기에서

public void endFlow(ExternalContext externalContext) { 
FlowUrlHandler handler = flowController.getFlowUrlHandler(); 
HttpServletRequest request = (HttpServletRequest) externalContext.getNativeRequest(); 
String stringKey = handler.getFlowExecutionKey(request); 
if (stringKey != null) { 
    FlowExecutorImpl flowExecutor = (FlowExecutorImpl) flowController.getFlowExecutor(); 
    FlowExecutionRepository repository = flowExecutor.getExecutionRepository(); 
    FlowExecutionKey key = repository.parseFlowExecutionKey(stringKey); 
    ExternalContextHolder.setExternalContext(externalContext); 
    FlowExecutionLock lock = null; 
    try{ 
    lock = repository.getLock(key); 
    }catch(NoSuchFlowExecutionException nsfee){  
    return; 
    } 
    lock.lock(); 
    try { 
    FlowExecution flowExecution = repository.getFlowExecution(key); 
    repository.removeFlowExecution(flowExecution); 
    } finally { 
    lock.unlock(); 
    } 
} 
} 

flowController (org.springframework.webflow.mvc.servlet.FlowController)가 스프링에 의해 주입

(아래 코드 참조) 나 처리 여부 확인 여부 현재 사용자 roomId에 액세스하고 난 endFlow 메소드를 호출 그 웹 플로우 설정 파일에 추가되었습니다. 위의 코드는 flow 실행을 완전히 제거하고 사용자가 이전 플로우로 돌아 가려는 경우 e1s1이라고 말하면 자동으로 새 플로우 실행 e2s1이 작성됩니다. 경우

유 필터 방식을 사용하고자하는 유 doFilter 방법에 필요한 모든이

public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) throws IOException, ServletException { 
HttpServletRequest req = (HttpServletRequest) request; 
HttpServletResponse resp = (HttpServletResponse) response; 
String roomId = req.getParameter("roomId"); 
ExternalContext externalContext = new ServletExternalContext(
    this.servletContext, req, resp); 
if (roomId != null) { 
    if (!currentUserHasAccess(roomId)) { 
     flowExecutionManager.endFlow(); 
     return; 
    } 
} 
chain.doFilter(request, response);  

this.servletContext의 filterConfig.getServletContext()

0

미안 해요, 내가 할 수있는을 통해 얻은 내가 할만한 충분한 포인트가 없기 때문에 주석을 달지는 못하지만, 유스 케이스에 대한 구현은 그것이해야하는 것보다 훨씬 복잡해 보입니다. 귀하의 질문에 코멘트 섹션에서 @ 패트릭에 의해 제안 된 것처럼, 왜 그냥 roomId 인수를 flowScope var에 저장할 수 없습니까? 흐름 파일에서 유효성 검사를 수행하거나 유효성 검사 방법을 호출하고 유효성 검사가 성공했는지 또는 실패한 경우 필요한 전이를 수행 할 수 있습니다. 프레임 워크가 처리해야하는 WebFlow 아티팩트 인 것처럼 스냅 샷은 신경 쓸 필요가 없습니다 ...