如何在动作方法中将请求转发到非JSF页面?

Sat*_*tya 2 navigation jsf forward

我想从JSF操作方法转发请求到非JSF页面.我在JSF操作中使用下面的代码:

public String submitUserResponse() {
    // ...

    parseResponse("foo.jsp", request, response);

    // ...

    return "nextpage";
}  

private String parseResponse(String uri, HttpServletRequest request, HttpServletResponse response) {
    if (uri != null) { 
        RequestDispatcher dispatcher = request.getRequestDispatcher(uri);
        dispatcher.forward(request, response);
        return null;
    }

    // ...

    return "xxxx";
}
Run Code Online (Sandbox Code Playgroud)

submitUserResponse()当用户点击来自JSF页面的提交按钮被称为动作方法,并且此方法返回nextpage的字符串.这里请求转发到正常流程中的下一个JSF页面.但在我的要求中,我需要将请求转发到下一个非JSF页面.它正在运行,但它在服务器中显示以下异常.

java.lang.IllegalStateException:在提交响应后无法转发

我观察到转发请求后使用的代码行parseResponse(...)return "nextpage";仍在执行dispatched.forward(uri).同样的事情发生了response.sendRedirect(url).这是怎么造成的,我该如何解决?

Bal*_*usC 11

我怀疑的是:1.为什么在使用dispatched.forward(uri)转发请求后执行下一行代码.在response.sendRedirect("")中发生了同样的事情.

因为你没有调用return跳出方法块.的include(),forward()sendRedirect()真的没有一些魔术,他们自动地做到这一点.那些仍然只是Java方法System#exit(),当然除了其他任何东西.它们将按顺序调用,代码将一直持续到方法块或return语句结束.这就是自己编写和控制的代码流程.

也就是说,正常的JSF实践是你应该使用ExternalContext#dispatch()ExternalContext#redirect()为此(第一个适用于你的情况).它不仅可以使您的代码免受JSF代码(如Servlet API)中不必要的"底层"混乱,而且还消除了调用FacesContext#responseComplete()您可能已经完成的修复初始IllegalStateException问题的需要.

简而言之:替换你的代码

public void submitUserResponse(){
    String uri = "foo.jsp";
    FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
}  
Run Code Online (Sandbox Code Playgroud)

就这样.无需从JSF引擎盖下不必要地挖掘Servlet请求/响应.请注意,该方法已声明void.这是完全可以接受的,虽然有些人知道它会像IDE一样抱怨它,如果是这样的话,那么就忽略它或替换String并添加return null;.

也可以看看:

  • 我做了同样的事.但我得到相同的异常消息.在这里,我想将请求重定向到另一个应用程序.所以我使用了public String editVerismo_initAction(){.......... FacesContext.getCurrentInstance().getExternalContext().redirect(redirectUrl); return null; } (2认同)