I am using Android Annotations to make requests to a server. I created the following interceptor based on the answer to this question
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
//It works after removing these two lines
String responseString = stringOf(response.getBody());
Log.d("RESPONSE", responseString);
return response;
}
public static String stringOf(InputStream inputStream) {
inputStream.mark(Integer.MAX_VALUE);
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder strBuilder = new StringBuilder();
String line;
try {
while ((line = r.readLine()) != null)
strBuilder.append(line);
} catch (IOException ignored) {}
try {
inputStream.reset();
} catch (IOException ignored) {}
return strBuilder.toString();
}
}
However, this is producing the following exception: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No content to map due to end-of-input
When I remove the following lines from the interceptor:
String responseString = stringOf(response.getBody());
Log.d("RESPONSE", responseString);
Everything works fine.
Here is my RestClient interface:
@Rest(rootUrl= "http://107.206.158.62:1337/api/", converters={MappingJackson2HttpMessageConverter.class}, interceptors = { LoggingInterceptor.class })
public interface IRestClient {
@Post("users/register/")
@Accept(MediaType.APPLICATION_JSON)
User register(@Body User user);
}
User Model:
public class User implements Serializable {
String first_name;
String last_name;
String email;
String password;
public User(){}
public User(String first_name, String last_name, String email, String password) {
this.first_name = first_name;
this.last_name = last_name;
this.email = email;
this.password = password;
}
//Getters and Setters
}
RestClient call in my Activity
@Click(R.id.bRegister)
@Background
void createAccount() {
User u = restClient.register(new User("Test Fname", "Test Lname", "[email protected]", "testpass"));
Log.d("User last name", u.getLast_name());
}
The server produces the following json:
{"first_name":"Test Fname","last_name":"Test Lname","email":"[email protected]"}
I'd like to be able to log the body of each response, and then return the response object. But it appears that reading the InputStream from the response first is causing some problems.
Log.d("RESPONSE", responseString);
Is yielding the correct server response, but then I run into the above exception when the MappingJackson2HttpMessageConverter kicks in.
Any help would be greatly appreciated! Happy New Years! :)
I think it's because when you read response you consume it and then it's empty. The interceptor acts before content parsing, so you consume your response to log it and then the parser finds it empty.
Logging response simply as reading it's content is not the best way to do this. I don't know the best technique but I keep commented response logging and then when I have a problem I stop with debug on a line into the intercept method and log request by watch panel, writing something like
Log.d("RESPONSE", stringOf(response.getBody()))
Then you can read logged data into Android Monitor panel. Obviously this response now is empty, so it will not be parsed and processed, but when you need you can log your response without rebuilding your project