5

我使用下面的(看起来像很多this)代码下载文件:下载从春天控制器文件抛出IllegalStateException异常

@RequestMapping(value = "/tunes/{file_name}", method = RequestMethod.GET) 
public void downloadTune(@PathVariable(value = "file_name") String tuneId, 
     HttpServletResponse response) { 
    perfomanceLogger.trace("=== Start retrieving tune with id: " + tuneId); 
    try { 
     String location = ""; 
     // try { 
     location = resourceManagementService.getArtifcatByIdAndType(tuneId, 
       ControllerConstants.TYPE_MP3); 
     String pathSeparator = File.separator; 

     if (location == null || location.equals("")) {// load the default 
                 // tune 
      location = System.getProperties().get("jboss.server.base.dir") 
        + pathSeparator + ServicesConstants.FILE_LOCATION 
        + pathSeparator + "ringtone_1.mp3"; 
      if (!new File(location).exists()) { 
       location = ""; 
      } 
     } 

     if (!location.equals("")) { 
      Path musicFile = Paths.get(location); 
      response.setContentType("audio/wav"); 
      response.setContentLength((int) Files.size(musicFile)); 
      try (OutputStream out = response.getOutputStream()) { 
       Files.copy(musicFile, out); 
       response.flushBuffer(); 
      } catch (Exception e) { 
       log.info("Could not stream tune with id: " + tuneId + " " 
         + e.getCause() + " " + e.getMessage()); 
      } 
     } 
    } catch (IOException | InvalidPathException | IllegalStateException e) { 
     log.info("Could not stream tune with id: " + tuneId + " " 
       + e.getMessage()); 

    } 
    perfomanceLogger.trace("=== Finished retrieving tune with id: " 
      + tuneId); 
} 

我使用Spring 3.2.2和Spring安全3.2。 0.M1和JBoss 7.1.1.Final。问题是有时我得到一个IllegalStateException。以下是堆栈跟踪:

2014-01-21 12:23:34,969 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/MyWebApplication].[appServlet]] (http--0.0.0.0-80-2) Servlet.service() for servlet appServlet threw exception: java.lang.IllegalStateException: Cannot create a session after the response has been committed 
at org.apache.catalina.connector.Request.doGetSession(Request.java:2636) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.connector.Request.getSession(Request.java:2375) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:841) [jbossweb-7.0.13.Final.jar:] 
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:255) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:255) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
at org.springframework.web.context.request.ServletRequestAttributes.getSession(ServletRequestAttributes.java:79) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.context.request.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:129) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.bind.support.DefaultSessionAttributeStore.storeAttribute(DefaultSessionAttributeStore.java:54) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.method.annotation.SessionAttributesHandler.storeAttributes(SessionAttributesHandler.java:123) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.method.annotation.ModelFactory.updateModel(ModelFactory.java:202) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getModelAndView(RequestMappingHandlerAdapter.java:842) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:751) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:150) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.0.M1.jar:3.2.0.M1] 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] 
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:567) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] 
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_21] 

会话有时会出现问题吗?

+0

我不认为这个问题在这段代码中。如果它有时候工作,似乎存在沟通问题。你确定对方工作正常吗? – andreadi

+0

我见过这个。它与Mojarra和JSF有关。我没有使用JSF,也没有在控制器中返回视图。 – ampofila

+0

我以前的评论是针对@pbal的答案的,堆栈溢出决定让它成为一个答案。 – ampofila

回答

2

摆脱

response.flushBuffer(); 

其提交的响应。

Servlet容器将负责提交响应并在需要时冲洗OutputStream

如果您的文件太大,您需要在开始下载之前亲自创建会话。


要回答评论:

好像你从来没有您的请求处理过程中产生的HttpSession

容器的实现HttpServletResponse提交响应(头文件),并在写入X字节数量(可配置并取决于容器)时开始刷新OutputStream。发生这种情况后,您无法强制容器创建一个HttpSession

显然你并没有自己创建HttpSession,但Spring使用它来管理它的模型属性,所以它必须创建它。它在

at org.springframework.web.method.annotation.ModelFactory.updateModel(ModelFactory.java:202) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 

简单的解决方案是让到HttpServletRequest的引用,并调用其getSession(boolean)方法,传递true以便它迫使HttpSession的创建。 在开始推送文件之前在任何地方执行此操作。

+0

我也试过这个。错误是一样的,不知何故响应被提交,然后会话无法创建。我找不到用Spring Security强制创建会话的方法,但我发现了一个解决方法,在Spring拦截器中,我通过预先处理请求来创建会话,但我仍然不明白为什么会发生这种情况。你能否定义“大”?这些文件相当小,大约50-300 KB。 – ampofila

+0

@ampofila看我的编辑。 –

+0

@ampofila如果是这样,你应该没问题。如果没有,就自己动手吧。 –

相关问题