2013-09-06 1 views
2

В моем контроллере Grails у меня есть изображение в виде байта []. Я хочу, чтобы написать эти байты [] непосредственно к response.outputStreamИзображение byte [] to response.outputStream в Grails приводит к «Не удается переслать после того, как ответ был зафиксирован»

я использую следующий код, чтобы сделать это:

def getImage() { 
    def attachment = Attachment.get(params.id) 
def imageByteArray = // some byte image from attachment (is a jpg image) 

     withCacheHeaders { 
      etag { 
       if (imageByteArray) 
        "${imageByteArray}".encodeAsSHA1() 
       else 
        "${new Date()}".encodeAsSHA1() 
      } 
      delegate.lastModified { 
       if(imageByteArray) { 
        attachment.lastUpdated ?: 0 
       } 
      } 

      generate { 
        response.setContentType("image/jpeg") 
        response.setHeader("Content-disposition", "filename=\"${imageName}${imageExtension}\"") 
        response.setContentLength(imageByteArray.size()) 

        def outputStream = null 
        try { 
         outputStream = response.outputStream 
         outputStream << imageByteArray 
         outputStream.flush() 

        } catch (IOException e){ 
         log.debug('getImage() - Canceled download?', e) 
        } finally { 
         if (outputStream != null){ 
          try { 
           outputStream.close() 
          } catch (IOException e) { 
           log.debug('Exception on close', e) 
          } 
         } 
        } 

      } 
     } // end withCacheHeaders 


     return null 
    } // end getImage 

Запуск моего приложения в производстве на сервере Tomcat, я получаю следующую ошибку иногда.

Что мне делать с потоком вывода? Является ли это flush() и/или close()? Как мне изменить код?

Sep 06, 2013 4:06:13 AM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [default] in context with path [] threw exception 
java.lang.IllegalStateException: Cannot forward after response has been committed 
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:349) 
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:314) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:279) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:270) 
    at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:222) 
    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.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:206) 
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:152) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    at org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:40) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69) 
    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.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:66) 
    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.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) 
    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:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1686) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:724) 

Я использую следующий фильтр:

class UserInfoFilters { 

    def filters = { 

     showInActionName(action: 'show', find: true) { 
//  all(controller:'*', action:'*') { 
      before = { 
       session.currentLocation = request.forwardURI - request.contextPath 
      } 
      after = { Map model -> 

      } 
      afterView = { Exception e -> 

      } 
     } 
    } 
} 
+0

какой код у вас есть после этого фрагмента? –

+0

@IgorArtamonov это последний код в моем действии – confile

+1

показать нам ваш полный контроллер grails, где именно вы пересылаете запрос. –

ответ

0

Ошибка вы показываете имеет дело с в какой момент код размещен запускается на выполнение. Исключение говорит

java.lang.IllegalStateException: Может не вперед после того, как реакция было совершено

An HttpServletResponse обычно стремится, то есть. заголовки отправляются, когда вы начинаете писать до OutputStream. На этом этапе вы не можете изменить заголовки или код состояния, и вы не можете использовать RequestDispatcher для forward() запрос на другой ресурс.

Проверьте, выполняете ли вы какие-либо из этих действий.

+0

Что мне нужно искать в моем коде? Я не знаю, что вызывает эту проблему? – confile

+0

Использование любых фильтров? –

+0

@JamesKleeh Я обновил свой ответ фильтром, который я использую. – confile

4

Grails не знает, что вы уже обработали ответ, и если вы не возвращаете ничего, то grails пытается применить логику по умолчанию.

Помещенный

return null 

в конце вашего действия.

+0

Это предотвратит ошибку? – confile

+0

следует. ты пробовал? –

+0

Я пробовал, но для появления ошибки требуется некоторое время. Ошибка не появляется все время. – confile