2

我想将请求从 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";
}

submitUserResponse()用户从 JSF 页面单击提交按钮时,将调用 action 方法,并且此方法返回nextpage字符串。这里请求以正常流程转发到下一个 JSF 页面。但在我的要求中,我需要将请求转发到下一个非 JSF 页面。它正在运行,但它在服务器中显示在异常下方。

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

我观察到parseResponse(...)return "nextpage";使用dispatched.forward(uri). 同样的事情也发生了response.sendRedirect(url)。这是如何引起的,我该如何解决?

4

2 回答 2

12

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

因为你没有调用return跳出方法块。, or真的没有他们自动做到这一点的include()魔力这些仍然只是 Java 方法,就像其他任何方法一样(当然除外)。它们将按顺序调用,代码将继续执行,直到方法块或语句结束。这只是关于自己编写和控制的代码流。forward()sendRedirect()System#exit()return

也就是说,正常的 JSF 实践是您应该使用ExternalContext#dispatch()or ExternalContext#redirect()(第一个适用于您的情况)。它不仅使您的代码免受 JSF 代码(如 Servlet API)中不必要的“幕后”混乱的影响,而且还消除了调用的需要FacesContext#responseComplete(),您也可以通过调用来解决最初的IllegalStateException问题。

简而言之:将您的代码替换为

public void submitUserResponse(){
    String uri = "foo.jsp";
    FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
}  

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

也可以看看:

于 2009-12-17T14:33:15.533 回答
2

这对我有用:

FacesContext.getCurrentInstance().getExternalContext().dispatch("/ServletUrl");

(特别注意正斜杠'/')

于 2010-12-26T12:48:24.047 回答