OkHttp拦截器之获取的内容
项目中,由于使用了cookie,约定的有效期是20分钟,所以有可以会遇到cookie失效,无权操作,需要再次登录的情况。
在每个地方都进行无权操作error的处理显得不现实,于是就想到了使用拦截器。
但是当使用拦截器获取()后,后面的操作就直接返回Failed了,估计是因为流只能被使用一次的原因。
@Override
public Response intercept(Chain chain) throws IOException {
Request request = ();
Response response = (request);
(":" + ().string());
return response;
}
后来,想到设置的 HttpLoggingInterceptor() 拦截器是如何获取到response的body的数据呢 ?
OkHttpClient client = new ()
.addInterceptor(new HttpLoggingInterceptor()
.setLevel())
.build();
于是乎是看了HttpLoggingInterceptor的源码
public final class HttpLoggingInterceptor implements Interceptor {
private static final Charset UTF8 = ("UTF-8");
@Override public Response intercept(Chain chain) throws IOException {
Level level = ;
Request request = ();
//如果Log Level 级别为NONOE,则不打印,直接返回
if (level == ) {
return (request);
}
//是否打印body
boolean logBody = level == ;
//是否打印header
boolean logHeaders = logBody || level == ;
//获得请求body
RequestBody requestBody = ();
//请求body是否为空
boolean hasRequestBody = requestBody != null;
//获得Connection,内部有route、socket、handshake、protocol方法
Connection connection = ();
//如果Connection为null,返回HTTP_1_1,否则返回()
Protocol protocol = connection != null ? () : Protocol.HTTP_1_1;
//比如: --> POST http://121.40.227.8:8088/api http/1.1
String requestStartMessage = "--> " + () + ' ' + () + ' ' + protocol;
if (!logHeaders && hasRequestBody) {
requestStartMessage += " (" + () + "-byte body)";
}
(requestStartMessage);
//打印 Request
if (logHeaders) {
if (hasRequestBody) {
// Request body headers are only present when installed as a network interceptor. Force
// them to be included (when available) so there values are known.
if (() != null) {
("Content-Type: " + ());
}
if (() != -1) {
("Content-Length: " + ());
}
}
Headers headers = ();
for (int i = 0, count = (); i < count; i++) {
String name = (i);
// Skip headers from the request body as they are explicitly logged above.
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
(name + ": " + (i));
}
}
if (!logBody || !hasRequestBody) {
("--> END " + ());
} else if (bodyEncoded(())) {
("--> END " + () + " (encoded body omitted)");
} else {
Buffer buffer = new Buffer();
(buffer);
//编码设为UTF-8
Charset charset = UTF8;
MediaType contentType = ();
if (contentType != null) {
charset = (UTF8);
}
("");
if (isPlaintext(buffer)) {
((charset));
("--> END " + ()
+ " (" + () + "-byte body)");
} else {
("--> END " + () + " (binary "
+ () + "-byte body omitted)");
}
}
}
//打印 Response
long startNs = ();
Response response;
try {
response = (request);
} catch (Exception e) {
("<-- HTTP FAILED: " + e);
throw e;
}
long tookMs = (() - startNs);
ResponseBody responseBody = ();
long contentLength = ();
String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
//比如 <-- 200 OK http://121.40.227.8:8088/api (36ms)
("<-- " + () + ' ' + () + ' '
+ ().url() + " (" + tookMs + "ms" + (!logHeaders ? ", "
+ bodySize + " body" : "") + ')');
if (logHeaders) {
Headers headers = ();
for (int i = 0, count = (); i < count; i++) {
((i) + ": " + (i));
}
if (!logBody || !(response)) {
("<-- END HTTP");
} else if (bodyEncoded(())) {
("<-- END HTTP (encoded body omitted)");
} else {
BufferedSource source = ();
(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = ();
Charset charset = UTF8;
MediaType contentType = ();
if (contentType != null) {
try {
charset = (UTF8);
} catch (UnsupportedCharsetException e) {
("");
("Couldn't decode the response body; charset is likely malformed.");
("<-- END HTTP");
return response;
}
}
if (!isPlaintext(buffer)) {
("");
("<-- END HTTP (binary " + () + "-byte body omitted)");
return response;
}
if (contentLength != 0) {
("");
//获取Response的body的字符串 并打印
(().readString(charset));
}
("<-- END HTTP (" + () + "-byte body)");
}
}
return response;
}
/**
* Returns true if the body in question probably contains human readable text. Uses a small sample
* of code points to detect unicode control characters commonly used in binary file signatures.
*/
static boolean isPlaintext(Buffer buffer) throws EOFException {
try {
Buffer prefix = new Buffer();
long byteCount = () < 64 ? () : 64;
(prefix, 0, byteCount);
for (int i = 0; i < 16; i++) {
if (()) {
break;
}
int codePoint = prefix.readUtf8CodePoint();
if ((codePoint) && !(codePoint)) {
return false;
}
}
return true;
} catch (EOFException e) {
return false; // Truncated UTF-8 sequence.
}
}
private boolean bodyEncoded(Headers headers) {
String contentEncoding = ("Content-Encoding");
return contentEncoding != null && !("identity");
}
}
然后,根据HttpLoggingInterceptor,就很容易得到responsebody的内容了
/**
* @Description 异常处理 拦截器
* Created by EthanCo on 2016/7/14.
*/
public class ErrorHandlerInterceptor implements Interceptor {
private static final Charset UTF8 = ("UTF-8");
@Override
public Response intercept(Chain chain) throws IOException {
Request request = ();
Response response = (request);
ResponseBody responseBody = ();
long contentLength = ();
//注意 >>>>>>>>> okhttp3.4.1这里变成了 !(response)
//if (!(response)) {
if(!(response)){ //HttpHeader -> 改成了 HttpHeaders,看版本进行选择
//END HTTP
} else if (bodyEncoded(())) {
//HTTP (encoded body omitted)
} else {
BufferedSource source = ();
(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = ();
Charset charset = UTF8;
MediaType contentType = ();
if (contentType != null) {
try {
charset = (UTF8);
} catch (UnsupportedCharsetException e) {
//Couldn't decode the response body; charset is likely malformed.
return response;
}
}
if (!isPlaintext(buffer)) {
("<-- END HTTP (binary " + () + "-byte body omitted)");
return response;
}
if (contentLength != 0) {
String result = ().readString(charset);
//获取到response的body的string字符串
//do something .... <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
("<-- END HTTP (" + () + "-byte body)");
}
return response;
}
static boolean isPlaintext(Buffer buffer) throws EOFException {
try {
Buffer prefix = new Buffer();
long byteCount = () < 64 ? () : 64;
(prefix, 0, byteCount);
for (int i = 0; i < 16; i++) {
if (()) {
break;
}
int codePoint = prefix.readUtf8CodePoint();
if ((codePoint) && !(codePoint)) {
return false;
}
}
return true;
} catch (EOFException e) {
return false; // Truncated UTF-8 sequence.
}
}
private boolean bodyEncoded(Headers headers) {
String contentEncoding = ("Content-Encoding");
return contentEncoding != null && !("identity");
}
}