2016-11-07 4 views
9

Mam kontroler, który obsługuje długi mechanizm odpytywania za pomocą Springs DeferredResult. W czasach, kiedy wywołać metodę kontroler wielokrotnie pojawia się poniższy wyjątek:Servlet.service() dla servlet jsp zwrócił wyjątek java.lang.IllegalStateException

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

Więc nie jest wezwaniem views/getLongPollingGraphData który przechodzi pewne identyfikatory i powrót z odpowiedzi json dla jednego lub brak id. Kiedy ładuję stronę wiele razy, co sprawia, że ​​ten URL wywołuje kilka razy, otrzymuję powyższy wyjątek.

Kwestia, że ​​twarz jest Używam onCompletion zwrotnego na DeferredResult usunąć DeferredResult z mapy kiedy to obaj razy na lub odpowiedź jest ustawiony na nim. Ale w przypadku tego wyjątku onCompletion nie jest wywoływany i pozostaje na mapie. Czytałem różne posty dotyczące tego wyjątku, ale nie mogłem się odnieść do żadnego z nich.

Poniżej znajduje się cały ślad stosu wyjątku i części mojej metody kontrolera.

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) 

metoda Kontroler:

@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; 
} 

Edit: myślę że org.apache.catalina.connector.ClientAbortException jest wyrzucane w pewnym momencie, gdy strona jest stale odświeżana. Używam org.springframework.web.servlet.handler.SimpleMappingExceptionResolver do obsługi na stronie jsp. Poniżej znajduje się kod:

głównego dyspozytora-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" rozwiązuje tylko wyjątki rodzaju "org.apache.catalina.connector.ClientAbortException". – rd22

+0

Twoja metoda kontrolera po prostu wyrzuca wyjątek, gdzie i jak sobie z nim poradziłeś? Dodaj tutaj kod, możemy spojrzeć na – developer

+0

@javaguy I zaktualizowałem szczegóły w pytaniu. – rd22

Odpowiedz

3

Problemem jest oczywista:

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

Zgłasza : IllegalStateException - jeśli metoda getReader() została już wywołana dla tego żądania

, aby dowiedzieć się, który filtr (lub coś podobnego) wywołuje metodę getReader() zanim servlet JSP robi, ustawić punkt przerwania do IllegalStateException. Zadzwoń do strony JSP. W stosie wywołań debuggera znajdź konkretną klasę implementacji interfejsu ServletRequest (jest to specyficzne dla kontenera). Ustaw punkt przerwania na getReader(), a następnie ponownie wywołaj JSP, a otrzymasz główną przyczynę.

Jeśli naprawdę trzeba zadzwonić getReader() lub getInputStream() wiele razy, o HttpServletRequestWrapper może pomóc, patrz np:

How to read InputStream multiple times

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

Bez kodu NO- całego projektu jeden będzie mógł znaleźć przyczynę tego wyjątku.