带有 java.lang.IllegalStateException 的 Servlet:提交响应后无法转发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22743803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:38:44  来源:igfitidea点击:

Servlet with java.lang.IllegalStateException: Cannot forward after response has been committed

javaservletshttprequesthttpresponse

提问by Martina

In my servlet I have this code:

在我的 servlet 我有这个代码:

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub

    Utils.CheckSession(request,response);

    String op = request.getParameter("op");
    int DaysToAdd = request.getParameter("daysToAdd") != null ? Integer.valueOf(request.getParameter("daysToAdd")) :  0;

    ArrayList<Giorno> giorni = new ArrayList<Giorno>();

    /*HERE I FILL ArrayList giorni and calculate other variables*/


    if ("cal".equals(op))
    {
        request.setAttribute("giorni", giorni);
        request.setAttribute("daysToAdd", DaysToAdd);
        request.getRequestDispatcher("GestioneCalendario.jsp").forward(request, response);

    }
    else if("utente".equals(op))
    {
        // ricavare abbonamento dell'utente
        String idu = (String) request.getAttribute("idu");
        Abbonamento a = null;
        int iDa = Utils.getIdAbbonamentoAttivoUtente(idu);
        a = Utils.getAbbonamentoFromId(iDa);
        request.setAttribute("abbonamento", a);
        request.getRequestDispatcher("Lezioni.jsp").forward(request, response);

    }
    else
    {
        request.setAttribute("giorni", giorni);
        request.setAttribute("daysToAdd", DaysToAdd);       
        request.getRequestDispatcher("GestioneLezioniNuovoLayout.jsp").forward(request, response);

    }

}

Maybe the problem is in the method CheckSession??

也许问题出在方法 CheckSession??

public static void CheckSession(HttpServletRequest request,
        HttpServletResponse response) {
    // TODO Auto-generated method stub
     HttpSession session = request.getSession(true);
     String logged = null;
     if (session!=null)
          logged = (String) session.getAttribute("logined");
     if(logged == null)
     {
         request.setAttribute("errore", "Devi loggarti!");
        try {
            request.getRequestDispatcher("Admin.jsp")
            .forward(request, response);
            return;
        } catch (ServletException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }

but it gives me this exception:

但它给了我这个例外:

GRAVE: Servlet.service() for servlet [TakeDates] in context with path [/Spinning] threw     exception
java.lang.IllegalStateException: Cannot forward after response has been committed
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:349)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at servlet.TakeDates.doGet(TakeDates.java:368)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)

the servlet is called with this url

使用此 url 调用 servlet

http://localhost:8080/Spinning/TakeDates?op=cal

Anyone can help me? thanks in advance!

任何人都可以帮助我吗?提前致谢!

采纳答案by robbmj

Somewhere in your code you have committed some response to the response object.

在您的代码中的某个地方,您已经向响应对象提交了一些响应。

You have to dispatch to your jsppage before you commit any output to the response object.

你必须派遣到你jsp,你犯任何输出到前页response object

From the Documentation

文档

forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.

forward 应该在响应提交给客户端之前调用(在响应正文输出被刷新之前)。如果已提交响应,则此方法将引发 IllegalStateException。响应缓冲区中未提交的输出在转发之前自动清除。

The problem is that you are forwarding to the admin.jsp page when you should be redirecting in the Utils.CheckSessionmethod

问题是您应该在Utils.CheckSession方法中重定向时转发到 admin.jsp 页面

request.getRequestDispatcher("Admin.jsp").forward(request, response);

Should be

应该

response.sendRedirect("Admin.jsp");
return false;

// in the doGet method
if (!Utils.CheckSession(request,response)) {
    return;
}

Redirects do not happen immediately, the servletwill continue execution and when it hits the next RequestDispatcher.forwardcall the exceptionis raised.

重定向不会立即发生,servlet它将继续执行,当它遇到下一个RequestDispatcher.forward调用时exception会引发。

The server needs to send the http: redirect status code in the http response, the browser then receives the response and requests resource specified by the redirect url.

服务器需要在http响应中发送http:redirect状态码,浏览器收到响应并请求重定向url指定的资源。

回答by Mwangi Thiga

Include a foward slash ie '/' on your urls. I had the same problem and a simple foward slash came to my rescue.

在您的网址上包含一个正斜杠,即“/”。我遇到了同样的问题,一个简单的向前斜线来拯救我。