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 Security 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

Я это видел. Это связано с Мохаррой и JSF. Я не использую JSF, и я не возвращаю представление в контроллер. – ampofila

+0

Мой предыдущий комментарий был для ответа @pbal, переполнение стека решило сделать его ответом в конце концов. – ampofila

ответ

2

Избавьтесь от

response.flushBuffer(); 

который совершает ответ.

Контейнер Servlet позаботится о том, чтобы выполнить отклик и промыть OutputStream, когда это необходимо.

Если ваш файл слишком велик, вы должны сами создать сеанс перед началом загрузки.


Чтобы ответить на комментарий:

Кажется, вы никогда не создавали HttpSession во время обработки запроса.

Реализация контейнера HttpServletResponse фиксирует ответ (заголовки) и начинает промывку OutputStream, когда вы написали X количество байтов (настраивается и зависит от контейнера). Вы не можете заставить контейнер создать 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 КБ. – ampofila

+0

@ampofila Посмотреть мое редактирование. –

+0

@ampofila Если это так, вы должны быть в порядке. Если это не так, просто сделайте это самостоятельно. –

Смежные вопросы