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