4 Stimmen

Ausgabe eines Binärdokuments auf der Grundlage eines HTML-Dokuments mit Hilfe von Filtern in Java

Dies ist vielleicht etwas verwirrend, aber ich habe einige Probleme. Mein Ziel ist es, ein HTML-Eingabedokument zu nehmen und dann dieses Dokument zu verarbeiten und die HTML-Daten zur Ausgabe eines Bilddokuments zu verwenden. Zum Beispiel wird ein Benutzer eine URL mit einem action=png im Querystring anfordern und dann wird der Filter für die URL und das ausgegebene Bilddokument aufgerufen.

Ich habe alles versucht, aber in meiner Umgebung (Websphere) kann ich nur einen Typ ausgeben. Wenn der Eingabetyp text/html ist, kann ich nur ein Textdokument ausgeben, ein binäres Dokument kann ich anscheinend nicht ausgeben. Warum? Weil ich jedes Mal eine illegale Statusausnahme erhalte.

[1/29/09 17:59:57:576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: Writer bereits erhalten [1/29/09 17:59:57:576 EST] 00000020 SystemErr R at com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream(SRTServletResponse.java:505)

Ich verwende Pseudocode, um nicht meinen gesamten Code preiszugeben:

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

Der Code der Wrapper-Klasse sieht im Wesentlichen so aus:

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

Und der Filtercode lautet wie folgt:

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.

Der Code funktioniert, wenn ich ein html-Textdokument eingeben möchte. Ich nehme an, dass dies aufgrund des offenen Printwriter-Streams funktioniert. Aber ich habe Probleme, in ein anderes Format zu wechseln. Im Grunde, weil ich response.getOutputStream() nicht aufrufen kann.

4voto

Joshua DeWald Punkte 2869

Das Problem scheint darin zu bestehen, dass Sie die Antwort Writer öffnen, bevor Sie die Antwort abschließen.

Es sieht so aus, als ob Sie dazu in der Lage sein sollten:

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

Sie können auf keinen Fall sowohl den Writer als auch den OutputStream sicher öffnen

0voto

Volker Stolz Punkte 7045

Ich habe keine Erfahrung mit Websphere, aber ein häufiges Problem besteht darin, dass Sie versuchen, die HTTP-Header zu manipulieren, nachdem Sie sich bereits zum Senden des Bodys verpflichtet haben - sobald der Webserver mit der Lieferung des Inhalts begonnen hat, können Sie die Header nicht mehr aktualisieren, da sie bereits gesendet wurden.

Vielleicht sollten Sie Ihre Dokumentation und Beispiele überarbeiten. Ich verstehe zum Beispiel nicht, warum Sie response.get*() aufrufen, ohne sich das Ergebnis anzusehen. Sind Sie sicher, dass dies notwendig ist, oder liegt es daran, dass Sie Ihren Code gekürzt haben?

Zum Wohl, Volker

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X