Servlet jsp的Servlet.service()引发了异常java.lang.IllegalStateException

时间:2016-11-07 05:17:11

标签: java spring

我有一个控制器,它使用弹簧DeferredResult来处理长轮询机制。有时当我多次调用控制器方法时,我得到以下异常:

java.lang.IllegalStateException: getOutputStream() has already been called for this response

所以有一个调用views/getLongPollingGraphData传递一些id并返回一个或没有id的json响应。当我多次加载页面时,有时会调用此URL,我会得到上述异常。

我遇到的问题是我使用onCompletion上的DeferredResult回调功能在地图超时或设置响应时从地图中移除DeferredResult。但是在此异常的情况下,onCompletion未被调用,并且它将保留在地图上。我已阅读有关此异常的不同帖子,但我无法与其中任何一个相关。

下面是异常的整个堆栈跟踪以及我的控制器方法的部分内容。

Nov 07, 2016 9:52:06 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.catalina.connector.Response.getWriter(Response.java:648)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:104)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
    at org.apache.jsp.WEB_002dINF.jsp.ClientAbortException_jsp._jspService(ClientAbortException_jsp.java:136)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:229)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:659)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:625)
    at org.apache.catalina.core.AsyncContextImpl$1.run(AsyncContextImpl.java:239)
    at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:382)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:215)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:299)
    at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1652)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)


Nov 07, 2016 9:52:06 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet main-dispatcher threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.catalina.connector.Response.getWriter(Response.java:648)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:104)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
    at org.apache.jsp.WEB_002dINF.jsp.ClientAbortException_jsp._jspService(ClientAbortException_jsp.java:136)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:229)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:659)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:625)
    at org.apache.catalina.core.AsyncContextImpl$1.run(AsyncContextImpl.java:239)
    at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:382)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:215)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:299)
    at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1652)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)


Nov 07, 2016 9:52:06 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [main-dispatcher] in context with path [/test-web] threw exception [java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause
java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.catalina.connector.Response.getWriter(Response.java:648)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:104)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
    at org.apache.jsp.WEB_002dINF.jsp.ClientAbortException_jsp._jspService(ClientAbortException_jsp.java:136)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:229)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:659)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:625)
    at org.apache.catalina.core.AsyncContextImpl$1.run(AsyncContextImpl.java:239)
    at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:382)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:215)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:299)
    at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1652)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

控制器方法:

@RequestMapping(value = "views/getLongPollingGraphData", method = RequestMethod.GET, headers = "Accept=application/json")
@ResponseBody
public DeferredResult<WebServiceResponse> getLongGraphData(
        HttpServletRequest request,
        @RequestParam(value = "ids") String ids) 
    throws Exception
{
    //perform operations

    //set time out this DeferredResult, after 5 seconds 
    final DeferredResult<WebServiceResponse> deferredResult = new DeferredResult<WebServiceResponse>(5000L, awrDefault);
    //listOfViews is a list containing ids
    mMapOfDeferredResultAndViews.put(deferredResult, listOfViews);
    //more operations

    deferredResult.onCompletion(new Runnable() {
        @Override
        public void run() 
        {
            mMapOfDeferredResultAndViews.remove(deferredResult);
        }
    });

    return deferredResult;
}

修改 我认为在页面不断刷新的某个时刻会抛出org.apache.catalina.connector.ClientAbortException。我使用org.springframework.web.servlet.handler.SimpleMappingExceptionResolver在jsp页面中处理它。以下是代码:

主调度-servlet.xml中

<bean
    class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.Exception">Exception</prop>
            <prop key="org.apache.catalina.connector.ClientAbortException">ClientAbortException</prop>
        </props>
    </property>
</bean>

ClientAbortException.jsp

<%@page import="org.slf4j.LoggerFactory"%>
<%@page import="org.slf4j.Logger"%>
<%@page import="com.test.model.messages.Messages"%>
<%@page import="java.util.Enumeration"%>
<%@page import="org.codehaus.jackson.map.ObjectMapper"%>
<%@page import="com.test.model.exceptions.TestException"%>
<%@page import="com.test.web.exchange.WebServiceResponse"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%
    Logger LOGGER = LoggerFactory.getLogger(this.getClass());
    LOGGER.debug("Exception caught in JSP: ", (Exception) request.getAttribute("exception"));

    boolean bReturnJson = false;

    Enumeration<?> headerNames = request.getHeaderNames();

    while (headerNames.hasMoreElements()) {
        String headerName = (String) headerNames.nextElement();

        if (headerName.equals("accept")) {
            if (request.getHeader(headerName).equals(
                    "application/json; charset=utf-8")) {
                bReturnJson = true;
            }

            break;
        }
    }

    if (bReturnJson) {
        WebServiceResponse awsr = new WebServiceResponse();

        TestException exception = new TestException(
                Messages.ERROR.toString(),
                (Exception) request.getAttribute("exception"));

        awsr.setException(exception);

        ObjectMapper mapper = new ObjectMapper();
        out.write(mapper.writeValueAsString(awsr)); 
    } else {
        ((Exception) request.getAttribute("exception")).printStackTrace();
%>

HTML error!

<%
            }
%>

1 个答案:

答案 0 :(得分:2)

问题很明显:

http://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#getInputStream--

  

抛出:       IllegalStateException - 如果已为此请求调用getReader()方法

要找出哪个Filter(或类似的东西)在JSP servlet之前调用getReader()方法,请将断点设置为IllegalStateException。调用你的JSP。在调试器的调用堆栈中,找出ServletRequest接口的特定实现类(这是特定于容器的)。设置一个断点到getReader(),然后再次调用你的JSP,你找到了根本原因。

如果你真的需要多次调用getReader()或getInputStream(),HttpServletRequestWrapper可能会对你有所帮助,例如:

How to read InputStream multiple times

https://gist.github.com/calo81/2071634

如果没有您的整个项目代码,任何人都无法找到此异常的原因。