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