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 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); } } }