Ho un servlet che gestisce determinate richieste e risposte HTTP. Voglio registrare il corpo della risposta prima di inviarlo al cliente. Esiste un modo per acquisire il corpo della risposta prima che venga inviato come oggetto HttpServletResponse
dal servlet?Cattura e registra il corpo della risposta
risposta
Se ho capito bene, si desidera registrare la risposta corpo? Questo è un compito piuttosto costoso, ma se questo è il requisito aziendale ...
Come indicato da @duffymo, un posto adatto per questo è un Filter
. È possibile acquisire il corpo della risposta sostituendo l'implementazione ServletResponse
con un'implementazione HttpServletResponseWrapper
che sostituisce lo HttpServletResponse#getWriter()
con una propria implementazione che copia il corpo della risposta in un buffer. Dopo aver proseguito con la catena di filtri con la risposta sostituita, è sufficiente registrare la copia.
Ecco un esempio di calcio d'inizio come il metodo doFilter()
può apparire come:
public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
final CopyPrintWriter writer = new CopyPrintWriter(response.getWriter());
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
@Override public PrintWriter getWriter() {
return writer;
}
});
logger.log(writer.getCopy());
}
Ecco come il CopyPrintWriter
può apparire come:
public class CopyPrintWriter extends PrintWriter {
private StringBuilder copy = new StringBuilder();
public CopyPrintWriter(Writer writer) {
super(writer);
}
@Override
public void write(int c) {
copy.append((char) c); // It is actually a char, not an int.
super.write(c);
}
@Override
public void write(char[] chars, int offset, int length) {
copy.append(chars, offset, length);
super.write(chars, offset, length);
}
@Override
public void write(String string, int offset, int length) {
copy.append(string, offset, length);
super.write(string, offset, length);
}
public String getCopy() {
return copy.toString();
}
}
Mappa del filtro su un url-pattern
per il quale vuoi per registrare le risposte per. Tieni presente che i contenuti binari/statici come immagini, CSS, file JS e così via non verranno registrati in questo modo. Vorresti escluderli utilizzando uno specifico url-pattern
, ad es. *.jsp
o solo sul servlet-name
del servlet in questione. Se si desidera comunque registrare il contenuto binario/statico (per il quale non vedo alcun beneficio), è necessario sostituire lo HttpServletResponse#getOutputStream()
allo stesso modo.
Forse un servlet filter può aiutarti. Pensa a una programmazione orientata agli aspetti per HTTP.
Un'alternativa a BalusC answer Utilizzo di TeeOutputStream per scrivere in due flussi di output alla volta.
public void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(baos);
chain.doFilter(req,new HttpServletResponseWrapper(res) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)
);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new DelegatingServletOutputStream (new TeeOutputStream(super.getOutputStream(), ps))
);
}
});
//Get Response body calling baos.toString();
}
Per il beneficio delle generazioni future ... quali librerie sono 'TeeOutputStream' e' DelegatingServletOutputStream'? –
È dalla primavera e apache io. 1) https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/mock/web/DelegatingServletOutputStream.html 2) https://commons.apache.org/proper/commons-io /javadocs/api-1.4/org/apache/commons/io/output/TeeOutputStream.html – Happier
Realizzo una versione di OutputStream senza dipendenza di terze parti, simile a @pdorgambide. È possibile trovare in this link.
- 1. Corpo risposta per richiesta/risposta Registrazione
- 2. corpo risposta registrazione espressa
- 3. Come cambiare il corpo della risposta con Charles?
- 4. Estensione Chrome - Come ottenere il corpo della risposta HTTP?
- 5. Leggere il corpo della risposta in un interceptor Spring Intel
- 6. GZIP il corpo della risposta in PlayFramework 2.0
- 7. Risposta HTTP 500 con il corpo?
- 8. Cattura risposta AJAX con selenio e pitone
- 9. Streaming corpo risposta okhttp
- 10. Leggere il corpo di una risposta 400?
- 11. ottenere il corpo di risposta di HttpResponse
- 12. Come cambiare il corpo in risposta OkHttp?
- 13. Come recuperare la lunghezza del corpo della risposta corrente?
- 14. Il metodo PATCH dovrebbe restituire tutti i campi della risorsa nel corpo della risposta?
- 15. Leggi corpo risposta di errore in Java
- 16. Visualizzazione del corpo della risposta con Hyper mostra solo la dimensione del corpo
- 17. Golang: come leggere il corpo di risposta di ReverseProxy?
- 18. Errore sempre "Il tipo ObjectContent 1 non è riuscito a serializzare il corpo della risposta ..."
- 19. Come impostare il corpo di risposta in javax.ws.rs.core.Response
- 20. Asserire che il corpo della risposta è una lista vuota con il resto sicuro
- 21. Scrittura del corpo di risposta con BaseHTTPRequestHandler
- 22. Fetch API: ottenere il titolo, parole chiave e il corpo del testo dalla risposta http
- 23. Cattura risposta a una soapUI test run
- 24. Primavera funzione di errore ResponseEntity & AJAX: non può accedere ai contenuti corpo della risposta
- 25. Come recuperare il codice di stato HTTP e il corpo della risposta quando viene generata un'eccezione RestClientException?
- 26. Problema unicode Node.js con il corpo di risposta HTTP
- 27. Delphi: Indy - come ottenere il corpo della risposta in caso di errore?
- 28. come ottenere corpo della risposta in okhttp quando il codice è 401
- 29. Come includere il corpo della risposta JSON in Trace di Spring Boot Actuator?
- 30. Non si ottiene il corpo della risposta per la richiesta http post in Android?
È necessario eseguire l'override non solo 'getWriter()', ma anche 'getOutputStream()' – pihentagy
E i problemi di codifica? – pihentagy
@pihentagy: 1) Se è necessario. 2) Usa lo stesso che è impostato dal metodo 'setCharacterEncoding()'. – BalusC