图像字节 [] 到 Grails 中的 response.outputStream 导致“响应提交后无法转发”

Posted

技术标签:

【中文标题】图像字节 [] 到 Grails 中的 response.outputStream 导致“响应提交后无法转发”【英文标题】:Image byte [] to response.outputStream in Grails leads to "Cannot forward after response has been committed" 【发布时间】:2013-09-10 13:38:35 【问题描述】:

在我的 Grails 控制器中,我有一个图像作为字节 []。我想把这个字节[]直接写到response.outputStream

我使用以下代码来做到这一点:

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

            
        
    

【问题讨论】:

这个sn-p之后你有什么代码? @IgorArtamonov 这是我操作中的最后一个代码 向我们展示您的完整 grails 控制器,您将请求转发到哪里。 @SajanChandran 看到上面的代码,我更新了我的问题。 【参考方案1】:

Grails 不知道您已经处理了响应,并且如果您没有返回任何内容,grails 会尝试应用默认逻辑。

return null

在您的操作结束时。

【讨论】:

我试了一下,但需要一段时间才会出现错误。错误并非一直出现。 是否需要flush() response.outputStream?【参考方案2】:

您显示的错误与您发布的代码在什么时候执行有关。例外说

java.lang.IllegalStateException:响应后无法转发 已承诺

HttpServletResponse 通常已提交,即。当您开始写入其OutputStream 时,将发送标头。此时,您无法更改标头或状态代码,也无法使用RequestDispatcherforward() 对另一个资源的请求。

检查你是否正在做这些事情。

【讨论】:

我必须在我的代码中寻找什么?不知道这个问题是什么原因造成的? @JamesKleeh 我用我正在使用的过滤器更新了我的回复。

以上是关于图像字节 [] 到 Grails 中的 response.outputStream 导致“响应提交后无法转发”的主要内容,如果未能解决你的问题,请参考以下文章

Grails Mongo GORM 插件 - 浮点和字节的映射是字符串而不是数字

在 Grails 4.2.2 中将 CSV 下载到浏览器

带有字节 [] 的 Grails 脚手架 404

如何使用 Grails Asset-Pipeline 插件从 Javascript 访问图像?

如何将字节数组中的图像发送到从android到具有Flask的python的url [重复]

Grails图像url加载但图像不加载?