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 = 5;
 | ||
|     private static final int DEFAULT_WRITE_TIMEOUT = 5;
 | ||
|     private static final int DEFAULT_READ_TIMEOUT = 5;
 | ||
|     public static String USERAGENT="";
 | ||
|     public static String LOCALUSERAGENT="";
 | ||
|     private Retrofit retrofit;
 | ||
|     private HttpApi httpApi;
 | ||
|     /**
 | ||
|      * 请求失败重连次数
 | ||
|      */
 | ||
|     private int RETRY_COUNT = 0;
 | ||
|     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.BODY);
 | ||
|         //设置 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;
 | ||
|         }
 | ||
|     }};
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| } |