2009-03-31 4 views
25

Desidero creare un filtro Servlet che leggerà il contenuto della risposta dopo che è stato elaborato e completato e restituirà tali informazioni in formato XML o PDF o altro. Ma non sono sicuro di come ottenere informazioni dall'oggetto HttpServletResponse. Come posso ottenere queste informazioni?Come posso leggere un flusso di output HttpServletReponses?

risposta

27

Aggiungere questo al file del filtro java

static class MyHttpServletResponseWrapper 
    extends HttpServletResponseWrapper { 

    private StringWriter sw = new StringWriter(BUFFER_SIZE); 

    public MyHttpServletResponseWrapper(HttpServletResponse response) { 
    super(response); 
    } 

    public PrintWriter getWriter() throws IOException { 
    return new PrintWriter(sw); 
    } 

    public ServletOutputStream getOutputStream() throws IOException { 
    throw new UnsupportedOperationException(); 
    } 

    public String toString() { 
    return sw.toString(); 
    } 
} 

Utilizzare il codice seguente:..

HttpServletResponse httpResponse = (HttpServletResponse) response; 
MyHttpServletResponseWrapper wrapper = 
    new MyHttpServletResponseWrapper(httpResponse); 

chain.doFilter(request, wrapper); 

String content = wrapper.toString(); 

La variabile contenuto ha ora il flusso di uscita È anche possibile lo fa per i contenuti binari

+1

Sì, usare un Servlet Reponse Wrapper e catturare l'output quando è scritto è il modo migliore per farlo, penso. – DyreSchlock

+1

Il codice che gestisce la richiesta utilizza comunque il flusso di output. È possibile utilizzare TeeOutputStream. (http://commons.apache.org/io/apidocs/org/apache/commons/io/output/TeeOutputStream.html) – DyreSchlock

+4

qual è il valore ragionevole di "BUFFER_SIZE"? – asgs

0

Non so se sia possibile ottenere dati da un oggetto HttpServletResponse come tale. Potrebbe avere più senso strutturare la tua applicazione in modo tale che le richieste vengano inoltrate ai gestori appropriati e trasmesse con gli oggetti di trasferimento dati, dai quali è possibile costruire la risposta finale appropriata. In questo modo, non modificherai mai più di un oggetto risposta o dovrai leggerne.

Non una risposta diretta, lo so, ma è così che lo farei dare la domanda.

+1

In definitiva, farei la stessa cosa e mi metterei in una posizione in cui non avrei dovuto leggere per la risposta. Ma l'elaborazione richiesta effettiva che sto usando è abbastanza nera e non può essere modificata:/ – DyreSchlock

1

Non credo che si possa fare necessariamente questo dato che scrivere sul flusso di output può far sì che i dati vengano svuotati al client prima che qualsiasi filtro servlet venga invocato post-popolazione. Come suggerisce iftrue, sarebbe consigliabile un'architettura diversa, per generare il tuo XML (ad esempio) e quindi rigenerare in qualsiasi formato di output desideri.

EDIT: Dopo aver letto la tua risposta a iftrue s' invio, se davvero non può interferire con l'elaborazione in corso, forse è necessario un servlet per delega la richiesta, catturare l'output dall'uscita originale, e poi munge come appropriato. Molto brutto, però :-(

2

Spring dispone ora di una funzionalità. Tutto ciò che devi fare è utilizzare [ContentCachingResponseWrapper], che ha metodo public byte [] getContentAsByteArray().

I Suggerisco di rendere WrapperFactory che consenta di renderlo configurabile, se utilizzare ResponseWrapper predefinito o ContentCachingResponseWrapper.