132 lines
4.9 KiB
Plaintext
132 lines
4.9 KiB
Plaintext
|
package com.novelbook.android.netutils;
|
||
|
|
||
|
import android.text.TextUtils;
|
||
|
import android.util.Log;
|
||
|
|
||
|
import java.io.IOException;
|
||
|
import java.lang.reflect.Field;
|
||
|
import java.lang.reflect.Modifier;
|
||
|
|
||
|
import okhttp3.Headers;
|
||
|
import okhttp3.Interceptor;
|
||
|
import okhttp3.Request;
|
||
|
import okhttp3.Response;
|
||
|
import okhttp3.ResponseBody;
|
||
|
import okhttp3.internal.http.RealResponseBody;
|
||
|
|
||
|
public class EncodingInterceptor implements Interceptor {
|
||
|
private final static String TAG= EncodingInterceptor.class.getSimpleName();
|
||
|
|
||
|
/**
|
||
|
* 自定义编码
|
||
|
*/
|
||
|
private String encoding;
|
||
|
|
||
|
public EncodingInterceptor(String encoding) {
|
||
|
this.encoding = encoding;
|
||
|
}
|
||
|
|
||
|
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
|
||
|
Request request = chain.request();
|
||
|
long start = System.nanoTime();
|
||
|
Log.d(TAG, String.format("EncodingInterceptor Sending request: %s, headers:%s ", request.url(), request.headers()));
|
||
|
Response response = chain.proceed(request);
|
||
|
long end = System.nanoTime();
|
||
|
Log.d(TAG,String.format("EncodingInterceptor Received response for %s in %.1fms%n %s", response.request().url(), (end - start) / 1e6d, response.headers()) );
|
||
|
|
||
|
|
||
|
String contentType = response.header("Content-Type");
|
||
|
if (!TextUtils.isEmpty(contentType) && contentType.contains("charset")) {
|
||
|
return response;
|
||
|
}
|
||
|
|
||
|
//add header
|
||
|
response.newBuilder()
|
||
|
.removeHeader("Pragma")
|
||
|
.header("Content-Type", (!TextUtils.isEmpty(contentType) ? contentType + "; ":"" ) + "charset=" + encoding)
|
||
|
.build();
|
||
|
//body charset
|
||
|
/* String contentTypeString = response.body().contentType().charset().name() ;
|
||
|
if (!TextUtils.isEmpty(contentTypeString) && contentTypeString.contains("charset")) {
|
||
|
return response;
|
||
|
}
|
||
|
contentTypeString = (!TextUtils.isEmpty(contentTypeString) ? contentTypeString + "; ":"" ) + "charset=" + encoding;
|
||
|
*/
|
||
|
|
||
|
|
||
|
settingClientCustomEncoding(response);
|
||
|
return response;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* setting client custom encoding when server not return encoding
|
||
|
* @param response
|
||
|
* @throws IOException
|
||
|
*/
|
||
|
private void settingClientCustomEncoding(Response response) throws IOException {
|
||
|
// setHeaderContentType(response);
|
||
|
setBodyContentType(response);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* set contentType in headers
|
||
|
* @param response
|
||
|
* @throws IOException
|
||
|
*/
|
||
|
private void setHeaderContentType(Response response) throws IOException {
|
||
|
String contentType = response.header("Content-Type");
|
||
|
if (!TextUtils.isEmpty(contentType) && contentType.contains("charset")) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// build new headers
|
||
|
Headers headers = response.headers();
|
||
|
Headers.Builder builder = headers.newBuilder();
|
||
|
builder.removeAll("Content-Type");
|
||
|
builder.add("Content-Type", (!TextUtils.isEmpty(contentType) ? contentType + "; ":"" ) + "charset=" + encoding);
|
||
|
headers = builder.build();
|
||
|
// setting headers using reflect
|
||
|
Class _response = Response.class;
|
||
|
try {
|
||
|
Field field = _response.getDeclaredField("headers");
|
||
|
field.setAccessible(true);
|
||
|
field.set(response, headers);
|
||
|
} catch (NoSuchFieldException e) {
|
||
|
throw new IOException("use reflect to setting header occurred an error", e);
|
||
|
} catch (IllegalAccessException e) {
|
||
|
throw new IOException("use reflect to setting header occurred an error", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* set body contentType
|
||
|
* @param response
|
||
|
* @throws IOException
|
||
|
*/
|
||
|
private void setBodyContentType(Response response) throws IOException {
|
||
|
ResponseBody body = response.body();
|
||
|
// setting body contentTypeString using reflect
|
||
|
Class tmp = RealResponseBody.class;
|
||
|
if( !(body instanceof RealResponseBody)){
|
||
|
return;
|
||
|
}
|
||
|
Class<? extends ResponseBody> aClass = body.getClass();
|
||
|
try {
|
||
|
Field field = aClass.getDeclaredField("contentTypeString");
|
||
|
field.setAccessible(true);
|
||
|
/* Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||
|
modifiersField.setAccessible(true);
|
||
|
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);*/
|
||
|
String contentTypeString = String.valueOf(field.get(body));
|
||
|
if (!TextUtils.isEmpty(contentTypeString) && contentTypeString.contains("charset")) {
|
||
|
return;
|
||
|
}
|
||
|
field.set(body, (!TextUtils.isEmpty(contentTypeString) ? contentTypeString + "; ":"" ) + "charset=" + encoding);
|
||
|
} catch (NoSuchFieldException e) {
|
||
|
throw new IOException("use reflect to setting header occurred an error", e);
|
||
|
} catch (IllegalAccessException e) {
|
||
|
throw new IOException("use reflect to setting header occurred an error", e);
|
||
|
}
|
||
|
}
|
||
|
}
|