struts2 - 在动作调用结果流下载PDF文件时间歇性地发生java.lang.IllegalStateException

Gop*_* SA 6 java jsp pdf-generation struts2 download

我有一个名为GetFile的动作,它直接打开一个文件下载框来打开PDF.

下面是struts.xml配置和相同的操作类.我使用结果类型作为流来实现这一点.我可以看到pdf下载框一直打开,我也可以下载该文件.

但是我发现昨晚有一些请求已经解雇了这个动作,它产生了以下错误.

    org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
        at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:570)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:452)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
        at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:159)
        at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
        at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:374)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:278)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
        at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
        at deshaw.irweb.web.interceptor.AuthInterceptor.intercept(AuthInterceptor.java:60)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510)
        at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
        at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:294)
        at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:183)
        at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:169)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response
        at org.apache.catalina.connector.Response.getWriter(Response.java:636)
        at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:205)
        at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
        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:182)
        at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:123)
        at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
        at org.apache.jsp.jsp.ServerError_jsp._jspService(ServerError_jsp.java:157)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
        ... 38 more     
Run Code Online (Sandbox Code Playgroud)

有人能告诉我可能导致问题的原因吗?我目前无法重现这个问题.我在某处看到它可能是因为关闭了下载对话框,但即使我尝试从多个浏览器中也不是这样.还检查了getOutputStream()已被调用此响应,但无法直接与我的问题相关,因为没有重定向到jsp,因为struts2操作直接导致结果流.

在struts.xml

<action name="GetFile" class="Class" method="DownloadFile">
            <result name="success" type="stream">
            <param name="contentType">contentType</param>
            <param name="contentDisposition">fileName</param>
            <param name="bufferSize">1024</param>
            <param name="inputName">inputStream</param> 
            </result>
</action>
Run Code Online (Sandbox Code Playgroud)

行动类

public String DownloadFile ()
{
        // create the object variable pdfdoc which is a custom object.
        // You can assume that the pdfdoc is properly constructed 
        // and getFileContent does what it is required to do, so
        // that the final pdf is generated.
        ...
        ...
        inputStream = new ByteArrayInputStream(pdfdoc.getFileContent());
        contentType = pdfdoc.getContentType();
        fileName = pdfdoc.getFileName();
        contentDisposition = doc.getContentDisposition();
        bufferSize = 1024;
        return "success";

}
Run Code Online (Sandbox Code Playgroud)

tib*_*tof 1

我在使用 Internet Explorer 时遇到了类似的问题,并通过在响应标头中添加以下内容来修复它:

response.setHeader("Expires","0");
response.setHeader("Pragma","cache");
response.setHeader("Cache-Control","private");
Run Code Online (Sandbox Code Playgroud)

也许您在日志中看到的请求是由 Internet Explorer 生成的。

看看这里这里

更新:要在日志中打印浏览器版本,您可以执行以下操作:

System.out.println(request.getHeader("User-Agent"));
Run Code Online (Sandbox Code Playgroud)