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