【问题标题】:java.lang.IllegalStateException content - dispositionjava.lang.IllegalStateException 内容 - 处置
【发布时间】:2013-03-11 02:45:54
【问题描述】:

我正在尝试使用content - disposition 将某些内容从服务器保存到客户端计算机。当我点击jsp中的按钮时,对话框打开,我选择保存文件。文件已保存,但出现此异常。我读过其他类似的主题,例如“某处,您的应用程序不止一次调用getOutputStreamgetWriter”。但我不知道/不明白在哪里?

@Controller
public class ExportPhonebook2 {

    @Autowired
    private PhoneBookService phoneBookSer;

    private void setResponseHeader(HttpServletResponse response, String imenikTXT, File file){
    response.setHeader("Content-Length", "" + file.length());
    response.setContentType("application/txt; charset=UTF-8");
    response.setHeader("content-disposition", "attachement; filename=imenik.txt" );
    response.setHeader("Content-Transfer-Encoding", "binary");
    } 

    @RequestMapping(value = "/exportPhonebook.html", method = RequestMethod.POST)
    public String exportPhonebook(Model model, HttpServletResponse response) {

        List<User> listOfAllUsers = phoneBookSer.fetchAllUsers();
        String imenik = "";

        for (User user : listOfAllUsers) {
            imenik = imenik + user.getPrezime() + " " + user.getIme() + ", Telefon: " + user.getTelefon() + ";\r\n" ;
        }


        try {

            File file = new File("c:\\imenik.txt");
            setResponseHeader(response, "imenik.txt", file);
            FileInputStream fileIn;
            fileIn = new FileInputStream(file);

            OutputStream outTXT = response.getOutputStream();

            byte[] outputByte = new byte[8192];
            //copy binary contect to output stream
            while(fileIn.read(outputByte, 0, 8192) != -1){
                outTXT.write(outputByte, 0, 8192);
            }
            fileIn.close();
            outTXT.flush();
            outTXT.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
    } catch (IOException e) {
               // TODO Auto-generated catch block
                e.printStackTrace();
    }

            return "homepage";
    }
}

堆栈跟踪:

Exception initializing page context
java.lang.IllegalStateException: Cannot create a session after the response has been   committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2705)
at org.apache.catalina.connector.Request.getSession(Request.java:2231)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:899)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:572)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:517)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:238)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:238)
at org.apache.jasper.runtime.PageContextImpl._initialize(PageContextImpl.java:146)
at org.apache.jasper.runtime.PageContextImpl.initialize(PageContextImpl.java:125)
at org.apache.jasper.runtime.JspFactoryImpl.internalGetPageContext(JspFactoryImpl.java:112)
at org.apache.jasper.runtime.JspFactoryImpl.getPageContext(JspFactoryImpl.java:65)
at org.apache.jsp.WEB_002dINF.jsp.homepage_jsp._jspService(homepage_jsp.java:58)
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)
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.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:229)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
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.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:328)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:175)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
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.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

【问题讨论】:

  • 我不做 Spring MVC,但你基本上应该告诉它不要返回视图。 return "homepage"; 行表示您正试图告诉它显示主页。但它实际上不应该显示任何东西。通过提供文件下载,响应已经被处理和提交。你不应该返回null 或设置一些标志/状态来告诉 Spring MVC 它不应该呈现视图吗?
  • 是的,你是对的,这就是问题所在。我将方法更改为 void 所以它不会返回任何东西,现在它工作得很好。非常感谢您的帮助!
  • 好的,我把它作为答案转发了。
  • 不相关,但仍有问题:您使用的是未定义的媒体类型 (application/txt),它是“附件”(不是“附件”),而 真的 没有HTTP 中的 Content-Transfer-Encoding 标头字段。
  • 好的,谢谢,我在网络上的某个地方找到了该示例并复制/粘贴了它。没有时间弄清楚所有事情,但我会在继续时纠正这些错误。

标签: java spring jsp response content-disposition


【解决方案1】:

这个特殊的异常是因为 Spring MVC 显然需要在渲染视图期间创建一个会话,但由于响应已经与文件下载一起提交,所以不能。但你真正的问题更大,Spring MVC 根本不应该渲染视图。

您需要告诉 Spring MVC 在从 Spring MVC 接管对 HTTP 响应的控制后不要渲染视图。否则它会尝试将呈现的视图附加到 HTTP 响应的末尾,这只会破坏文件下载。

我不做 Spring MVC,所以我不能从头顶回答,但似乎只从控制器的操作方法返回 void 而不是 String 就足以告诉 Spring MVC不渲染视图。

【讨论】:

    【解决方案2】:

    java.lang.IllegalStateException: 响应提交后无法创建会话

    会话创建需要在正文之前将会话 cookie 写入 HTTP 标头。在您刷新并关闭您的响应后,有东西正在尝试创建会话。

    考虑在编写响应之前创建会话。

    【讨论】:

    • 我知道您熟悉 JSF。 OP 在 Spring MVC 中面临的问题与在 JSF 中在 JSF 操作方法中提供文件下载后未调用 FacesContext#responseComplete() 时所面临的问题完全相同。这与会话/cookies 完全无关。查看stacktrace,at org.springframework.web.servlet.view.AbstractView.render 这一行表明Spring MVC 正在尝试渲染视图。
    • 我以为可能是这样的,但我已经有一段时间没有看 Spring MVC 了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 2016-09-10
    • 2010-10-30
    相关资源
    最近更新 更多