2013-08-06 51 views
5

Mam akcję, która zapisuje bezpośrednio do strumienia wyjściowego. Czasami pojawia się następujący błędów:Błąd przetwarzania GroovyPageView: getOutputStream() został już wywołany dla tej odpowiedzi

Error processing GroovyPageView: getOutputStream() has already been called for this response 
Caused by getOutputStream() has already been called for this response 

i ten jeden:

Executing action [getImage] of controller [buddyis.ItemController] caused exception: Runtime error executing action 
Caused by Broken pipe 

Jak mogę rozwiązać te problemy? Akcja, której używam, jest wymieniona poniżej.

UWAGA: Używam Tomcat 7.0.42, jeśli jest to ważne!

def getImage() { 
    byte [] imageByteArray = // some image bytes 

    response.setHeader 'Content-disposition', "attachment; filename=\"${imageName}${imageExtension}\"" 
    response.setContentType("image/pjpeg; charset=UTF-8") 
    response.contentLength = imageByteArray.size() 
    response.outputStream.write(imageByteArray) 
    response.outputStream.flush() 
    response.outputStream.close() 
    return 
} 
+0

Spróbuj wyrenderować coś (manekina) w celu indeksowania lub renderowania kodu statusu i zobacz, czy nadal występuje problem. Możesz zacząć od 'render (status: 200)' lub co najmniej 'render 'Done" 'etc przed powrotem. – dmahapatro

+0

Dlaczego to robisz? – confile

+0

Skorzystaj z [tego pytania] (http://stackoverflow.com/questions/13184603/grails-error-using-httpservletresponse-to-export-file-for-download). – dmahapatro

Odpowiedz

6

Nie wiem, dlaczego pojawia się ten błąd, jednak tutaj jest to, co robię, że działa za każdym razem.

I nie nazywaj .flush() lub .close()

response.setContentType("application/octet-stream") 
response.setHeader("Content-disposition", "filename=\"${name}\"") 
response.setContentLength(imageByteArray.size()) 
response.outputStream << imageByteArray 

Stosując powyższe to działa dobrze, dopóki nie okazało się, użytkownik może anulować pobieranie, który spowodował wyjątek. Jest to pełny kod używam zamiast response.outputStream << imageByteArray:

def outputStream = null 
    try { 
     outputStream = response.outputStream 
     outputStream << imageByteArray 

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

Używam Tomcat 7.0.42, jeśli jest to ważne dla odpowiedzi? Dlaczego ContentType "application/octet-stream"? – confile

+0

Myślę, że używam 7.0.39, więc nie powinno to mieć znaczenia. Jeśli chodzi o typ zawartości - zezwalam na pobieranie/wysyłanie wielu typów plików. To wydaje się działać dla wszystkich. –

+0

Okay, a co z .flush() i .close() dlaczego tego nie potrzebujesz? – confile

0

miałem ten problem podczas uruchomionych na Tomcat 2.5 Grails: 7.0.55.3 iz Grails java-melody zainstalowaną wtyczkę. Po odinstalowaniu java-melody działało dobrze