I'm using retrofit2 and I need to log all request and response. Request and response works perfectly, All I need is to log those request/response, I tried almost every solution, which I found here, but did not find solution. I don't understand what's wrong is here
this is my code
class Factory {
private final static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static NetworkApi.Factory serverApi;
private static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
private Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RequestApi.BASE_URL)
.client(httpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
public static NetworkApi getApi() {
if (BuildConfig.DEBUG){
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder()
.addHeader("Content-Type", "application/json");
return chain.proceed(builder.build());
}
});
httpClient.interceptors().add(interceptor);
}
if (serverApi == null){
serverApi = new NetworkApi.Factory();
}
return serverApi.retrofit.create(NetworkApi.class);
}
}
libraries :
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
Try to use the OkHttpClient as follows:
private OkHttpClient createDefaultOkHttpClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return new OkHttpClient().newBuilder()
.addInterceptor(interceptor)
.build();
}
Then just set this to your retrofit builder:
Retrofit retrofitAsync = new Retrofit.Builder()
.baseUrl(BASE_URL_APPS)
.client(createDefaultOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(rxAdapter)
.build();
Make API call like this.
ApiFactory.java
public class ApiFactory {
/**
* Base URL for API calls
*/
private static final String BASE_URL = "";
public ApiFactory() {
}
private static Retrofit provideRestAdapter() {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(BaseApplication.getInstance().getOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
public static <S> S createService(Class<S> serviceClass) {
return provideRestAdapter().create(serviceClass);
}
}
LoginService Interface
public interface LoginService {
/**
* To Post FormUrlEncoded to web service
*
* @return Call Object of Type JsonObject
*/
@FormUrlEncoded
@POST("api/login")
Call<JsonObject> login(@Field("email") String email,
@Field("password") String password,
@Field("devicetype") String devicetype,
@Field("deviceid") String deviceid);
}
Make API call here
private void emailLoginRequest() {
LoginService loginService = ApiFactory.createService(LoginService.class);
Call<JsonObject> call = loginService.login(edtEmail.getText().toString(),edtPassword.getText().toString(),mDeviceType,mDeviceToken);
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
hideProgressDialog();
if (response.isSuccessful()) {
LOGD(TAG, "onResponse 0: " + response.body().toString());
LoginResponse loginResponse = new Gson().fromJson(response.body().toString(), LoginResponse.class);
System.out.println("+++ get message >> " + loginResponse.getMessage());
int status = loginResponse.getStatus();
}else {
LOGD(TAG, "response fail 0: " + response.body());
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
hideProgressDialog();
LOGD(TAG, "onFailure: " + t.getMessage());
}
});
}
LoginResponse Make changes as per yours.
public class LoginResponse {
@SerializedName("status")
@Expose
private Integer status;
@SerializedName("message")
@Expose
private String message;
@SerializedName("data")
@Expose
private Data data;
/**
* No args constructor for use in serialization
*
*/
public LoginResponse() {
Sample response model
// {
// "status": 1,
// "data": {
// "user_id": "565464564",
// "email": "email@email.com",
// "fullname": "james",
// "username": "james123",
// "country": "54654654",
// "city": "56546465546",
// "token": "dfgdfgdfg545465465464564"
// },
// "message": "Login successfull"
// }
}
/**
*
* @param message
* @param status
* @param data
*/
public LoginResponse(Integer status, String message, Data data) {
this.status = status;
this.message = message;
this.data = data;
}
/**
*
* @return
* The status
*/
public Integer getStatus() {
return status;
}
/**
*
* @param status
* The status
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
*
* @return
* The message
*/
public String getMessage() {
return message;
}
/**
*
* @param message
* The message
*/
public void setMessage(String message) {
this.message = message;
}
/**
* @return The data
*/
public Data getData() {
return data;
}
/**
* @param data The data
*/
public void setData(Data data) {
this.data = data;
}
public class Data {
@SerializedName("user_id")
@Expose
private String userId;
@SerializedName("email")
@Expose
private String email;
/**
* No args constructor for use in serialization
*/
public Data() {
}
/**
* @param email
* @param userId
*/
public Data(String userId, String email) {
this.userId = userId;
this.email = email;
}
/**
* @return The userId
*/
public String getUserId() {
return userId;
}
/**
* @param userId The user_id
*/
public void setUserId(String userId) {
this.userId = userId;
}
/**
* @return The email
*/
public String getEmail() {
return email;
}
/**
* @param email The email
*/
public void setEmail(String email) {
this.email = email;
}
}
}
Enjoy!
I it would be better to add interceptors while creating client using Builder as below code. If you notice we add two interceptors
- Network interceptor > addNetworkInterceptor
- Interceptor > addInterceptor
The main difference is network interceptor only works when there is a real request (not loading from caching). Interceptor log data on both cases loading from network or cache.
Also make sure you are imorting the correct BuildConfig (sometimes autocompletion import it from one of your libraries, then it will be always false)
`OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Logger networkLayerLogger = new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtils.d("NetworkLayer", message);
}
};
HttpLoggingInterceptor.Logger appLayerLogger = new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtils.d("ApplicationLayer", message);
}
};
HttpLoggingInterceptor networkLogging = new HttpLoggingInterceptor(networkLayerLogger);
HttpLoggingInterceptor appLogging = new HttpLoggingInterceptor(appLayerLogger);
networkLogging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
appLogging.setLevel(HttpLoggingInterceptor.Level.BODY);
clientBuilder.addNetworkInterceptor(networkLogging);
clientBuilder.addInterceptor(appLogging);
}
`