-
-
Notifications
You must be signed in to change notification settings - Fork 41
Custom Interceptor
Besides our implementation, you can also make your custom implementation of ParseNetworkInterceptor
.
Here is the basic structure of a ParseNetworkInterceptor implementation:
public class ParseDemoInterceptor implements ParseNetworkInterceptor {
@Override
public ParseHttpResponse intercept(Chain chain) throws IOException {
ParseHttpRequest request = chain.getRequest();
ParseHttpResponse response = chain.proceed(request);
return response;
}
}
The chain.proceed(request)
is the key part of a ParseNetworkInterceptor
implementation. This is where HTTP communication happens. You have to proceed the request to get the response.
Another important thing is about the body of the request and response. For request body, you can call ParseHttpBody#writeTo(OutputStream)
to get the content of the body and it is safe to call it multiple times. For response body, since the content of the bodies are InputStream from network, they can only be consumed once. If your interceptor needs to check the response bodies, typically there are two ways to do that.
The first way is after your interceptor consumes the body, you make a new body before you proceed the request and return the response. Here is an example:
public class ParseDemoInterceptor implements ParseNetworkInterceptor {
@Override
public ParseHttpResponse intercept(Chain chain) throws IOException {
ParseHttpRequest request = chain.getRequest();
ParseHttpResponse response = chain.proceed(request);
// Consume the response body
ByteArrayOutputStream responseBodyByteStream = new ByteArrayOutputStream();
int n;
byte[] buffer = new byte[1024];
while ((n = response.getContent().read(buffer, 0, buffer.length)) != -1) {
responseBodyByteStream.write(buffer, 0, n);
}
final byte[] responseBodyBytes = responseBodyByteStream.toByteArray();
Log.i("Response_Body", new String(responseBodyBytes));
// Make a new response before return the response
response = new ParseHttpResponse.Builder(response)
.setContent(new ByteArrayInputStream(responseBodyBytes))
.build();
return response;
}
}
This way is pretty straightforward and easy to implement. But the drawback is in fact you make a new request/response body stream, if you have other interceptors which need the real body stream(like a time logging interceptor to log the response time), they may not work well.
The second way is instead of consuming the body stream in your interceptors, you wrap the raw body stream with a proxy stream and then proceed/return the proxy stream. In this way, since your interceptors do not consume the raw body stream, all things should be fine. Check the source code of ParseLogInterceptor
for more details.
Finally, ParseInterceptor can be chained and is trigged one by one. This means the changes you make in the previous interceptors will have an effect on the following interceptors. So if you make some mistakes in your ParseInterceptor, it may cause error in Parse SDK.