2012-06-20 9 views
8

Ich verwende eine einfache Spring Interceptor-Klasse, um alle REST-Anforderungen/Antworten für das RestTemplate-Objekt in meiner Android-App zu protokollieren. Bis jetzt funktioniert alles gut.Den Antworttext in einem Android Spring Interceptor lesen

public class LoggerInterceptor implements ClientHttpRequestInterceptor { 

@Override 
public ClientHttpResponse intercept(HttpRequest request, byte[] body, 
    ClientHttpRequestExecution execution) throws IOException { 

Log.d(TAG, "Request body: " + new String(body)); 
// ...more log statements... 

ClientHttpResponse response = execution.execute(request, body); 

Log.d(TAG, "Response Headers: " + response.getHeaders()); 

return response; 
} 

Bei der Initialisierung nenne ich:

List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(); 
LoggerInterceptor loggerInterceptor = new LoggerInterceptor(); 
interceptors.add(loggerInterceptor); 
restTemplate.setInterceptors(interceptors); 

Allerdings kann ich response.getBody() in dem oben beschriebenen Verfahren nicht anmelden, da die Input einmal verbraucht werden und lösen eine Illegal, wenn es später wieder verbraucht wird. Gibt es einen Weg, um den Antwortkörper zu protokollieren?

Antwort

11

Um mehrere Aufrufe von response.getBody() zu ermöglichen, umbrechen Sie Ihre ClientHttpRequestFactory in einer BufferingClientHttpRequestFactory.

+0

Mit dem 3.1 Spring-Framework oder später ist dies definitiv eine elegantere Lösung. – Nachi

6

Implementieren Sie ClientHttpResponse selbst und fügen Sie eine setBody(byte[] body) Methode hinzu und überschreiben Sie getBody. In Ihrem obigen Code können Sie dann das Byte-Array in einer ByteArrayInputStream speichern, protokollieren, was Sie wollen, und dann das Byte-Array zurück in die Instanz Ihrer Klasse setzen, die ClientHttpResponse implementiert, und die Sie dann zurückgeben können.