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