Pregunta

Esto puede ser un poco confuso pero tengo algunos problemas. Mi objetivo es tomar un documento HTML de entrada y luego procesar ese documento y usar los datos HTML para generar un documento de imagen. Por ejemplo, un usuario solicitará una URL, con alguna acción = png en la cadena de consulta y luego se invocará el filtro para la URL y el documento de imagen de salida.

He intentado todo pero en mi entorno (Websphere), solo puedo generar un tipo. Si el tipo de entrada es text / html, entonces solo puedo generar un documento de texto, parece que no puedo generar un documento binario. ¿Por qué? Porque recibo una excepción de estado ilegal cada vez.

[29/01/09 17: 59: 57: 576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: Escritor ya obtenido [1/29/09 17: 59: 57: 576 EST] 00000020 SystemErr R en com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream (SRTServletResponse.java:505)

Estoy usando pseudocódigo para no revelar todo mi código:

<filter>
    <filter-name>TestFilter</filter-name>
    <filter-class>
        com.util.TestFilter
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/index_test2.html</url-pattern>
</filter-mapping>

El código de la clase Wrapper es esencialmente esto:

public class ContentCaptureServletResponse extends HttpServletResponseWrapper { 
    private ByteArrayOutputStream contentBuffer;
    private PrintWriter writer; 
    public PrintWriter getWriter() throws IOException {
        if (writer == null) {
            contentBuffer = new ByteArrayOutputStream();
            writer = new PrintWriter(contentBuffer);
        }       
        return writer;
    }   
    public String getContent(){
        try {
            writer = getWriter();
        } catch (IOException e) {           
            e.printStackTrace();
        }
        writer.flush();
        String xhtmlContent = new String(contentBuffer.toByteArray());                 
        System.out.println(xhtmlContent);                
        return xhtmlContent; 
    }
}

Y el código de filtro es este:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        final String renderType = request.getParameter("R"); 
        final String renderClassName = request.getParameter("C");
        if ((renderType != null) && (renderClassName != null)) {
            try {
                this.setFilterChain(filterChain);
                response.setContentType("image/png");
                PrintWriter out = response.getWriter();                             
                // I call getWriter but not BOTH!
                //response.getOutputStream();               
                response.getWriter();

                // Build up the HTML document into a string.
                    CaptureResponse capContent = new CaptureResponse(response);            
                this.mainFilterChain.doFilter(req, );
                String myString = capHtmlContent.getContent();

                // What I really want to do here is output an output stream
                // so I can write a binary image
                processStr(myString);
                response.getOutputStream();             
                response.write(binaryimage)

            } catch (Exception e) {            
                e.printStackTrace();
            }
            // No data will be output to the user.
        } else {
            filterChain.doFilter(request, response);
        }  // End of if-else        
    } // End of the method.

El código funciona si quiero tomar algún documento de texto html de entrada. Supongo que debido a la corriente de escritora abierta. Pero tengo problemas para ir a un formato diferente. Básicamente, porque no puedo llamar a response.getOutputStream ()

¿Fue útil?

Solución

El problema parece ser que está abriendo el escritor de respuestas antes de ajustar la respuesta.

Parece que deberías poder hacer:

this.setFilterChain(filterChain);
CaptureContent capContent = new CaptureResponse(response);
doFilter()
process();
response.setContentType("image/png");
response.getOutputStream().write(imagedata);

Definitivamente no puede abrir con seguridad tanto el Writer como el OutputStream

Otros consejos

No tengo experiencia con Websphere, pero un problema común es que intenta manipular el encabezado HTTP después de haberse comprometido a enviar el cuerpo; una vez que el servidor web comenzó a entregar el contenido, ya no puede actualizar los encabezados desde ya han sido enviados.

Tal vez necesite revisar su documentación y ejemplos. Por ejemplo, no veo por qué llamas a response.get * () sin mirar realmente el resultado. ¿Estás seguro de que esto es necesario o es porque recortaste tu código?

Saludos,   Volker

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top