2016-11-07 1066 views
9

我有一個控制器,它使用Springs DeferredResult來處理長輪詢機制。在我多次調用該控制器的方法的時候,我得到了以下異常:Servlet jsp的Servlet.service()引發異常java.lang.IllegalStateException

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

所以有一個叫views/getLongPollingGraphData它通過一些IDS和回報與一個或沒有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! 

<% 
      } 
%> 
+0

@ScaryWombat'ClientAbortException.jsp'只能解析'org.apache.catalina.connector.ClientAbortException'類型的異常。 – rd22

+0

你的控制器方法只是拋出異常,你在哪裏以及如何處理它?在這裏添加代碼,我們可以看看 – developer

+0

@javaguy我更新了問題中的細節。 – rd22

回答

3

的問題是顯而易見的:

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

拋出: IllegalStateException - 如果getReader()方法已經被調用此請求

爲了找到答案,這過濾器(或類似的東西)調用getReader()方法,你的JSP的servlet不前,一個破發點設置IllegalStateException異常。調用你的JSP。在調試器的調用堆棧中,找出接口ServletRequest的具體實現類(這是特定於容器的)。設置一個斷點到getReader(),然後再次調用你的JSP,你有根本原因。

如果你真的必須調用getReader()或的getInputStream()多次,一了HttpServletRequestWrapper可能會幫助你,例如參見:

How to read InputStream multiple times

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

沒有你的整個項目的代碼NO-人們將能夠找出這個例外的原因。

相關問題