363 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
		
		
			
		
	
	
			363 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
|  | package com.novelbook.android.netutils; | |||
|  | 
 | |||
|  | 
 | |||
|  | import android.content.Context; | |||
|  | import android.util.Log; | |||
|  | 
 | |||
|  | import com.novelbook.android.MyApp; | |||
|  | import com.novelbook.android.netapi.HttpApi; | |||
|  | import com.novelbook.android.netapi.RandomHost; | |||
|  | import com.novelbook.android.netapi.URLConstant; | |||
|  | import com.novelbook.android.utils.CommonUtil; | |||
|  | import com.novelbook.android.utils.FileUtils; | |||
|  | 
 | |||
|  | 
 | |||
|  | import org.json.JSONException; | |||
|  | import org.json.JSONObject; | |||
|  | 
 | |||
|  | import java.io.File; | |||
|  | import java.io.IOException; | |||
|  | import java.security.KeyManagementException; | |||
|  | import java.security.NoSuchAlgorithmException; | |||
|  | import java.security.cert.CertificateException; | |||
|  | import java.util.Locale; | |||
|  | import java.util.concurrent.TimeUnit; | |||
|  | 
 | |||
|  | import javax.net.ssl.HostnameVerifier; | |||
|  | import javax.net.ssl.SSLContext; | |||
|  | import javax.net.ssl.SSLSession; | |||
|  | import javax.net.ssl.TrustManager; | |||
|  | import javax.net.ssl.X509TrustManager; | |||
|  | 
 | |||
|  | import io.reactivex.Observable; | |||
|  | import io.reactivex.android.schedulers.AndroidSchedulers; | |||
|  | import io.reactivex.observers.DisposableObserver; | |||
|  | import io.reactivex.schedulers.Schedulers; | |||
|  | import okhttp3.Cache; | |||
|  | import okhttp3.CacheControl; | |||
|  | import okhttp3.Interceptor; | |||
|  | import okhttp3.OkHttpClient; | |||
|  | import okhttp3.Request; | |||
|  | import okhttp3.Response; | |||
|  | import okhttp3.logging.HttpLoggingInterceptor; | |||
|  | import retrofit2.Retrofit; | |||
|  | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; | |||
|  | import retrofit2.converter.gson.GsonConverterFactory; | |||
|  | 
 | |||
|  | import static com.novelbook.android.netapi.URLConstant.getRootUrl; | |||
|  | //import static com.novelbook.android.netapi.URLConstant.newRootUrl; | |||
|  | //import static com.novelbook.android.netutils.NetUtil.getHost; | |||
|  | 
 | |||
|  | public class HttpMethods { | |||
|  |     public String TAG = "HttpMethods"; | |||
|  |     public static final String CACHE_NAME = "ZHUIKE"; | |||
|  |    //public static String BASE_URL = getBaseUrl(); | |||
|  |     private static final int DEFAULT_CONNECT_TIMEOUT = 10; | |||
|  |     private static final int DEFAULT_WRITE_TIMEOUT = 10; | |||
|  |     private static final int DEFAULT_READ_TIMEOUT = 10; | |||
|  |     public static String USERAGENT=""; | |||
|  |     public static String LOCALUSERAGENT=""; | |||
|  |     private Retrofit retrofit; | |||
|  |     private HttpApi httpApi; | |||
|  |     /** | |||
|  |      * 请求失败重连次数 | |||
|  |      */ | |||
|  |     private int RETRY_COUNT = 3; | |||
|  |     private OkHttpClient.Builder okHttpBuilder; | |||
|  |     private OkHttpClient okHttpClient; | |||
|  |     //构造方法私有 | |||
|  |     private HttpMethods() { | |||
|  | 
 | |||
|  | 
 | |||
|  |         okHttpClient = getClient(); | |||
|  | 
 | |||
|  |         retrofit = new Retrofit.Builder() | |||
|  |                 .client(okHttpClient) | |||
|  |                 .addConverterFactory(GsonConverterFactory.create())//json转换成JavaBean | |||
|  |                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |||
|  |                 .baseUrl(getRootUrl()) | |||
|  |                 .build(); | |||
|  |         httpApi = retrofit.create(HttpApi.class); | |||
|  |     } | |||
|  | 
 | |||
|  |     //在访问HttpMethods时创建单例 | |||
|  |     private static class SingletonHolder { | |||
|  |         private static final HttpMethods INSTANCE = new HttpMethods(); | |||
|  | 
 | |||
|  | 
 | |||
|  |     } | |||
|  |     //获取单例 | |||
|  |     public static HttpMethods getInstance(String keyUrl) { | |||
|  |        // SingletonHolder.INSTANCE.changeBaseUrl(NetUtil.getUrl(keyUrl)); | |||
|  |         try { | |||
|  |             SingletonHolder.INSTANCE.ChangeNoForward(keyUrl); | |||
|  |         } catch (JSONException e) { | |||
|  |             e.printStackTrace(); | |||
|  |         } | |||
|  |         return SingletonHolder.INSTANCE; | |||
|  |     } | |||
|  |     public void ChangeNoForward(String keyUrl) throws JSONException { | |||
|  |        // SingletonHolder.INSTANCE.changeBaseUrl(NetUtil.getUrl(keyUrl)); | |||
|  |      //   RandomHost rh = new RandomHost( getHost() ,keyUrl); | |||
|  |      //   okHttpBuilder.addInterceptor(new RetryInterceptor(rh)); | |||
|  |        // okHttpBuilder.addInterceptor(new RetryInterceptor()); | |||
|  |         okHttpBuilder.followRedirects(false); | |||
|  |         okHttpBuilder.retryOnConnectionFailure(false); | |||
|  | 
 | |||
|  |         retrofit = new Retrofit.Builder() | |||
|  |                 .client(okHttpBuilder.build()) | |||
|  |                 .addConverterFactory(GsonConverterFactory.create()) | |||
|  |                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |||
|  |                 .baseUrl(getRootUrl()) | |||
|  |                 .build(); | |||
|  |         httpApi = retrofit.create(HttpApi.class); | |||
|  |     } | |||
|  |     //获取单例 | |||
|  |     public static HttpMethods getInstance() { | |||
|  |         return SingletonHolder.INSTANCE; | |||
|  |     } | |||
|  |     //获取单例 | |||
|  |     public static OkHttpClient getOkClient() { | |||
|  |         return SingletonHolder.INSTANCE.okHttpClient; | |||
|  |     } | |||
|  |     public static OkHttpClient getOkClient(int maxAge) { | |||
|  |         maxAgeForce =maxAge; | |||
|  |         return SingletonHolder.INSTANCE.okHttpClient; | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 获取retrofit | |||
|  |      * | |||
|  |      * @returnc | |||
|  |      */ | |||
|  |     public Retrofit getRetrofit() { | |||
|  |         return retrofit; | |||
|  |     } | |||
|  | 
 | |||
|  |     /*public void changeBaseUrl(String baseUrl) { | |||
|  |         okHttpBuilder.addInterceptor(new RetryInterceptor()); | |||
|  |         //okHttpBuilder.retryOnConnectionFailure(false); | |||
|  |         retrofit = new Retrofit.Builder() | |||
|  |                 .client(okHttpBuilder.build()) | |||
|  |                 .addConverterFactory(GsonConverterFactory.create()) | |||
|  |                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |||
|  |                 .baseUrl(baseUrl) | |||
|  |                 .build(); | |||
|  |         httpApi = retrofit.create(HttpApi.class); | |||
|  |     }*/ | |||
|  |    /* public void changeBaseUrl() { | |||
|  |        changeBaseUrl(newBaseUrl()); | |||
|  |     }*/ | |||
|  |     /** | |||
|  |      * 获取httpService | |||
|  |      * | |||
|  |      * @return | |||
|  |      */ | |||
|  |     public HttpApi getHttpApi() { | |||
|  |         return httpApi; | |||
|  |     } | |||
|  |     public HttpApi getHttpApi(int maxAge) { | |||
|  |         maxAgeForce =maxAge; | |||
|  |         return httpApi; | |||
|  |     } | |||
|  | 
 | |||
|  |     private static final int  maxAge = 60*60; //一小时; | |||
|  |     private static int  maxAgeForce =0; //默认没有强制; | |||
|  | 
 | |||
|  |     private OkHttpClient getClient(){ | |||
|  |         //手动创建一个OkHttpClient并设置超时时间 | |||
|  |         okHttpBuilder = new OkHttpClient.Builder(); | |||
|  | 
 | |||
|  |         /** | |||
|  |          * 设置缓存 | |||
|  |          */ | |||
|  |         File cacheFile = new File(FileUtils.getDiskCacheDir(MyApp.applicationContext), CACHE_NAME); | |||
|  |         Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); | |||
|  |         Log.d(TAG, "getClient: to set cach control"); | |||
|  |         //  okHttpBuilder.cache(cache).addInterceptor(cacheInterceptor); | |||
|  |         okHttpBuilder.cache(cache) | |||
|  |                //  .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) | |||
|  |                 .addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE); | |||
|  | 
 | |||
|  |         /** | |||
|  |          * 设置头信息 | |||
|  |          */ | |||
|  | 
 | |||
|  | 
 | |||
|  |     /*    Interceptor headerInterceptor = new Interceptor() { | |||
|  |             @Override | |||
|  |             public Response intercept(Chain chain) throws IOException { | |||
|  |                 Request originalRequest = chain.request(); | |||
|  |                *//* Request.Builder requestBuilder = originalRequest.newBuilder() | |||
|  |                         .addHeader("Accept-Encoding", Locale.getDefault().toString()) | |||
|  |                       //  .addHeader("Host", "testapi.wujike.com.cn") | |||
|  |                         .addHeader("Connection", "Keep-Alive") | |||
|  |                         .addHeader("Device", "Android") | |||
|  |                         .method(originalRequest.method(), originalRequest.body()); | |||
|  |                *//* | |||
|  |                 Request.Builder requestBuilder = originalRequest.newBuilder() | |||
|  |                        //  .addHeader("Accept-Encoding", "gzip") | |||
|  |                     //    .addHeader("Accept-Encoding", Locale.getDefault().toString() ) | |||
|  |                         //   .addHeader("Accept", "application/json") | |||
|  |                          //     .addHeader("Content-Type", "application/json; charset=utf-8") | |||
|  |                       //  .addHeader("Device", "Android") | |||
|  |                          .removeHeader("User-Agent").addHeader("User-Agent",USERAGENT) //加 随机agent | |||
|  |                         .tag(NetUtil.currentRequestTag) | |||
|  |                         .method(originalRequest.method(), originalRequest.body()); | |||
|  | 
 | |||
|  |                 //  requestBuilder.addHeader("Authorization", "Bearer" + BaseConstant.TOKEN);//添加请求头信息,服务器进行token有效性验证 | |||
|  |                 Request request = requestBuilder.build(); | |||
|  |                 return chain.proceed(request); | |||
|  |             } | |||
|  |         };*/ | |||
|  |       //  okHttpBuilder.addInterceptor(headerInterceptor); | |||
|  | 
 | |||
|  | 
 | |||
|  | //        if (BuildConfig.DEBUG) { | |||
|  |         HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { | |||
|  |             @Override | |||
|  |             public void log(String message) { | |||
|  |                 Log.d(TAG, message); | |||
|  |             } | |||
|  | 
 | |||
|  | 
 | |||
|  |         }); | |||
|  |         loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); | |||
|  |         //设置 Debug Log 模式 | |||
|  |         okHttpBuilder.addInterceptor(loggingInterceptor); | |||
|  |       // okHttpBuilder.addInterceptor(new RetryInterceptor()); | |||
|  |         //设置编码 | |||
|  |      //   EncodingInterceptor encodingInterceptor = new EncodingInterceptor("gbk"); | |||
|  |       //  okHttpBuilder.addInterceptor(encodingInterceptor); | |||
|  | 
 | |||
|  | //        } | |||
|  | 
 | |||
|  |         /** | |||
|  |          * 设置超时和重新连接 | |||
|  |          */ | |||
|  |         okHttpBuilder.connectTimeout(DEFAULT_CONNECT_TIMEOUT, TimeUnit.SECONDS); | |||
|  |         okHttpBuilder.readTimeout(DEFAULT_WRITE_TIMEOUT, TimeUnit.SECONDS); | |||
|  |         okHttpBuilder.writeTimeout(DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS); | |||
|  | 
 | |||
|  |         //错误重连 | |||
|  |         okHttpBuilder.retryOnConnectionFailure(true); | |||
|  | 
 | |||
|  |         okHttpBuilder.addInterceptor(new RetryInterceptor()); | |||
|  | 
 | |||
|  |         okHttpBuilder.hostnameVerifier(SSLSocketClient.getHostnameVerifier()); | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |         // Install the all-trusting trust manager | |||
|  |         final SSLContext sslContext; | |||
|  |         try { | |||
|  |             sslContext = SSLContext.getInstance("SSL"); | |||
|  | 
 | |||
|  |             sslContext.init(null, trustAllCerts, | |||
|  |                     new java.security.SecureRandom()); | |||
|  |             // Create an ssl socket factory with our all-trusting manager | |||
|  |             final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext | |||
|  |                     .getSocketFactory(); | |||
|  | 
 | |||
|  |           //  okHttpBuilder.sslSocketFactory(sslSocketFactory); | |||
|  |            /* okHttpBuilder.hostnameVerifier(new HostnameVerifier() { | |||
|  | 
 | |||
|  |                 @Override | |||
|  |                 public boolean verify(String hostname, SSLSession session) { | |||
|  |                     // TODO Auto-generated method stub | |||
|  |                     return true; | |||
|  | 
 | |||
|  |                 } | |||
|  |             });*/ | |||
|  |         } catch (NoSuchAlgorithmException | KeyManagementException e) { | |||
|  |             e.printStackTrace(); | |||
|  |         } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |         return  okHttpBuilder.build(); | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 设置订阅 和 所在的线程环境 | |||
|  |      */ | |||
|  |     public <T> void toSubscribe(Observable<T> o, DisposableObserver<T> s) { | |||
|  | 
 | |||
|  |         o.subscribeOn(Schedulers.io()) | |||
|  |                 .unsubscribeOn(Schedulers.io()) | |||
|  |                 .observeOn(AndroidSchedulers.mainThread()) | |||
|  |                 .retry(RETRY_COUNT)//请求失败重连次数 | |||
|  |                 .subscribe(s); | |||
|  | 
 | |||
|  |     } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     private final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() { | |||
|  |         @Override | |||
|  |         public Response intercept(Chain chain) throws IOException { | |||
|  |             Response originalResponse = chain.proceed(chain.request()); | |||
|  | 
 | |||
|  |             String cacheControl = originalResponse.header("Cache-Control"); | |||
|  |             Log.d(TAG, String.format("intercept:url %s, get cache controle: %s, maxAgeForce %s",originalResponse.request().url(), cacheControl,maxAgeForce)); | |||
|  |             //int maxAge = 60*60; //一小时 | |||
|  |             if (maxAgeForce >0 ||cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") || | |||
|  |                     cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) { //目标网站禁用cache则设置为1小时 | |||
|  | 
 | |||
|  |                 int age = maxAgeForce >0? maxAgeForce :maxAge; | |||
|  |                 Log.d(TAG, "intercept: add maxAge: "+ age); | |||
|  |                 return originalResponse.newBuilder() | |||
|  |                         .removeHeader("Pragma") | |||
|  |                         .header("Cache-Control", "public, max-age=" + age) | |||
|  |                         .build(); | |||
|  |             } else { | |||
|  |            /*    return originalResponse.newBuilder() | |||
|  |                         .removeHeader("Pragma") | |||
|  |                         .header("Cache-Control", "public, max-age=" + maxAge) | |||
|  |                         .build();*/ | |||
|  |               return originalResponse; | |||
|  |             } | |||
|  |         } | |||
|  |     }; | |||
|  | 
 | |||
|  |     private final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() { | |||
|  |         @Override | |||
|  |         public Response intercept(Chain chain) throws IOException { | |||
|  |             Request request = chain.request(); | |||
|  |             if (!NetUtil.isNetworkConnected()) { | |||
|  |                 int maxStale =  60 * 60 * 24 * 28; | |||
|  |                 request = request.newBuilder() | |||
|  |                         .removeHeader("Pragma") | |||
|  |                         .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) | |||
|  |                         .build(); | |||
|  |             } | |||
|  |             return chain.proceed(request); | |||
|  |         } | |||
|  |     }; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |     final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { | |||
|  |         @Override | |||
|  |         public void checkClientTrusted( | |||
|  |                 java.security.cert.X509Certificate[] chain, | |||
|  |                 String authType) throws CertificateException { | |||
|  |         } | |||
|  | 
 | |||
|  |         @Override | |||
|  |         public void checkServerTrusted( | |||
|  |                 java.security.cert.X509Certificate[] chain, | |||
|  |                 String authType) throws CertificateException { | |||
|  |         } | |||
|  | 
 | |||
|  |         @Override | |||
|  |         public java.security.cert.X509Certificate[] getAcceptedIssuers() { | |||
|  |             return null; | |||
|  |         } | |||
|  |     }}; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | } |