2015-02-24 7 views
35

Я использую перехватчик, и я хотел бы зарегистрировать тело запроса, который я делаю, но я не вижу никакого способа сделать это.OkHttp как зарегистрировать тело запроса

Возможно ли это?

public class LoggingInterceptor implements Interceptor { 
    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 

     long t1 = System.nanoTime(); 
     Response response = chain.proceed(request); 
     long t2 = System.nanoTime(); 

     double time = (t2 - t1)/1e6d; 

     if (request.method().equals("GET")) { 
      Logs.info(String.format("GET " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), response.code(), response.headers(), response.body().charStream())); 
     } else if (request.method().equals("POST")) { 
      Logs.info(String.format("POST " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body(), response.code(), response.headers(), response.body().charStream())); 
     } else if (request.method().equals("PUT")) { 
      Logs.info(String.format("PUT " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body().toString(), response.code(), response.headers(), response.body().charStream())); 
     } else if (request.method().equals("DELETE")) { 
      Logs.info(String.format("DELETE " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITHOUT_BODY, request.url(), time, request.headers(), response.code(), response.headers())); 
     } 

     return response; 
    } 
} 

и результат:

POST [some url] in 88,7ms 
    ZoneName: touraine 
    Source: Android 
    body: [email protected] <-request.body().toString() gives me this, but I would like the content string 
    Response: 500 
    Date: Tue, 24 Feb 2015 10:14:22 GMT 
    body: [some content] 

ответ

77

ответ Николы не работает для меня. Я предполагаю, что изменения в ByteString#toString() изменены. Это решение работает для меня:

private static String bodyToString(final Request request){ 

    try { 
     final Request copy = request.newBuilder().build(); 
     final Buffer buffer = new Buffer(); 
     copy.body().writeTo(buffer); 
     return buffer.readUtf8(); 
    } catch (final IOException e) { 
     return "did not work"; 
    } 
} 

Из документации readUtf8():

Удаляет все байты из этого, декодирует их как UTF-8 и возвращает строку.

, который должен быть тем, что вы хотите.

+0

Спасибо большое, это работает как шарм:) –

+0

На всякий случай, знаете ли вы, как это сделать, используя объект Response? (копирование тела ответа) –

+1

@MathieudeBrito try 'response.body(). string()'. – aga

8

Я попытался прокомментировать правильный ответ от @msung, но моя репутация недостаточно высока.

Вот модификация, которую я сделал, чтобы распечатать RequestBody перед тем, как сделать полный запрос. Отлично работает. Благодаря

private static String bodyToString(final RequestBody request){ 
     try { 
      final RequestBody copy = request; 
      final Buffer buffer = new Buffer(); 
      copy.writeTo(buffer); 
      return buffer.readUtf8(); 
     } 
     catch (final IOException e) { 
      return "did not work"; 
     } 
} 
+0

, просто возвращающее набор случайных строк. не работает – pks

+0

Вы сериализовали его каким-либо образом? – bold

+0

нет, я его не сериализую ...можете ли вы отредактировать свой ответ, чтобы сделать все, чтобы точно напечатать тело запроса? – pks

8

EDIT

Потому что я вижу, есть еще некоторые люди, заинтересованные на этот пост, вот окончательный вариант (до следующего улучшения) моего журнала перехватчика. Надеюсь, это спасет некоторых из вас, ребята, время.

Пожалуйста, обратите внимание, что этот код использует OkHttp 2.2.0Retrofit 1.9.0)

import com.squareup.okhttp.*; 
import okio.Buffer; 
import java.io.IOException; 

public class LoggingInterceptor implements Interceptor { 

private static final String F_BREAK = " %n"; 
private static final String F_URL = " %s"; 
private static final String F_TIME = " in %.1fms"; 
private static final String F_HEADERS = "%s"; 
private static final String F_RESPONSE = F_BREAK + "Response: %d"; 
private static final String F_BODY = "body: %s"; 

private static final String F_BREAKER = F_BREAK + "-------------------------------------------" + F_BREAK; 
private static final String F_REQUEST_WITHOUT_BODY = F_URL + F_TIME + F_BREAK + F_HEADERS; 
private static final String F_RESPONSE_WITHOUT_BODY = F_RESPONSE + F_BREAK + F_HEADERS + F_BREAKER; 
private static final String F_REQUEST_WITH_BODY = F_URL + F_TIME + F_BREAK + F_HEADERS + F_BODY + F_BREAK; 
private static final String F_RESPONSE_WITH_BODY = F_RESPONSE + F_BREAK + F_HEADERS + F_BODY + F_BREAK + F_BREAKER; 

@Override 
public Response intercept(Chain chain) throws IOException { 
    Request request = chain.request(); 

    long t1 = System.nanoTime(); 
    Response response = chain.proceed(request); 
    long t2 = System.nanoTime(); 

    MediaType contentType = null; 
    String bodyString = null; 
    if (response.body() != null) { 
     contentType = response.body().contentType(); 
     bodyString = response.body().string(); 
    } 

    double time = (t2 - t1)/1e6d; 

    if (request.method().equals("GET")) { 
     System.out.println(String.format("GET " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), response.code(), response.headers(), stringifyResponseBody(bodyString))); 
    } else if (request.method().equals("POST")) { 
     System.out.println(String.format("POST " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), stringifyRequestBody(request), response.code(), response.headers(), stringifyResponseBody(bodyString))); 
    } else if (request.method().equals("PUT")) { 
     System.out.println(String.format("PUT " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body().toString(), response.code(), response.headers(), stringifyResponseBody(bodyString))); 
    } else if (request.method().equals("DELETE")) { 
     System.out.println(String.format("DELETE " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITHOUT_BODY, request.url(), time, request.headers(), response.code(), response.headers())); 
    } 

    if (response.body() != null) { 
     ResponseBody body = ResponseBody.create(contentType, bodyString); 
     return response.newBuilder().body(body).build(); 
    } else { 
     return response; 
    } 
} 


private static String stringifyRequestBody(Request request) { 
    try { 
     final Request copy = request.newBuilder().build(); 
     final Buffer buffer = new Buffer(); 
     copy.body().writeTo(buffer); 
     return buffer.readUtf8(); 
    } catch (final IOException e) { 
     return "did not work"; 
    } 
} 

public String stringifyResponseBody(String responseBody) { 
    return responseBody; 
} 
} 
+1

Если вы можете опубликовать импорт вверх, это будет очень полезно, так как есть несколько версий OKHttp, и я играю в догадку и проверяю, какие из них у вас здесь. Спасибо – Silmarilos

+0

Готово, надеюсь, что это поможет;) –

+0

Он делает, большое спасибо за разъяснение Матье. – Silmarilos

1

версии, которая обрабатывает запросы с или без тела:

private String stringifyRequestBody(Request request) { 
    if (request.body() != null) { 
     try { 
      final Request copy = request.newBuilder().build(); 
      final Buffer buffer = new Buffer(); 
      copy.body().writeTo(buffer); 
      return buffer.readUtf8(); 
     } catch (final IOException e) { 
      Log.w(TAG, "Failed to stringify request body: " + e.getMessage()); 
     } 
    } 
    return ""; 
}