目录
okhttp、retrofit初始化
自定义安全套接字socket
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_SUPPORT_VERSION);
}
return s;
}
}
用SSLSocketFactory初始化OKHttp
private Map<Integer, RequestIsSuccess> requestInterfMap = new TreeMap<>();
private APIManager.APIInterface apiInterface;
private Retrofit retrofit;
private OkHttpClient okHttpClient;
public X509TrustManager createX509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
};
}
public SSLSocketFactory createTLSSocketFactory(X509TrustManager x509TrustManager) {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
Log.e("APIManager", " -=-=- createSSLSocketFactory: Create SSLSocketFactory Error", e);
}
return ssfFactory;
}
X509TrustManager x509 = createX509TrustManager();
public SSLSocketFactory socketFactory = new Tls12SocketFactory(createTLSSocketFactory(x509));
public HostnameVerifier createHostnameVerifier() {
return (hostname, session) -> true;
}
private CookieJar createCookieJar() {
return new CookieJar() {
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieList.addAll(cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
try {
if (url.isHttps() && !BASE_URL.contains(String.valueOf(url.port()))) {
setIpPort(true, url.host(), String.valueOf(url.port()));
}
} catch (ConcurrentModificationException e) {
Log.e("APIManager", " -=-=- loadForRequest: e", e);
}
return cookieList;
}
};
}
初始化okhttp
public void init() {
cookieList = new ArrayList<>();
requestMap = new HashMap<>();
okHttpClient = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.sslSocketFactory(socketFactory, x509)
.hostnameVerifier(createHostnameVerifier())
.cookieJar(createCookieJar()).build();
}
初始化retrofit
public APIManager setIpPort(boolean isHttps, String ip, String port) {
IP_PORT = ip + ":" + port;
String prefix;
if (isHttps) prefix = "https://";
else prefix = "http://";
BASE_URL = prefix + IP_PORT/* + "/" + PROJECT_ROOT_NAME + "/"*/;
Log.d("APIManager", " -=-=- setIpPort: BaseUrl:" + BASE_URL);
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(okHttpClient).build();
apiInterface = retrofit.create(APIManager.APIInterface.class);
return this;
}
定义retrofit请求接口
一般请求使用第一个接口,多文件上传请求使用第二个接口
private interface APIInterface {
@FormUrlEncoded
@POST("{path}/{apiPath}")
Call<ResponseBody> request(@Path("path") String path, @Path("apiPath") String apiPath, @FieldMap Map<String, Object> requestMap);
@POST("{path}/{apiPath}")
Call<ResponseBody> uploadFiles(@Path("path") String path, @Path("apiPath") String apiPath, @Body MultipartBody multipartBody);
}
定义retrofit回调
private Call<ResponseBody> retrofitEnqueue(int hashCode, String path, String apiPath, Call<ResponseBody> responseBodyCall) {
responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// Log.d("APIManager", " -=-=- onResponse: call:" + call);
try {
if (response.code() == 200) {
String body = response.body().string();
Log.d("APIManager", " -=-=- onResponse: api:" + apiPath + " body:" + body);
if (checkIsReLogin(body)) return;
if (!checkIsSuccess(body, hashCode)) return;
handler.obtainMessage(REQUEST_SUCCESS_TRUE, hashCode, 0, body).sendToTarget();
} else {
handler.obtainMessage(REQUEST_FAILED, hashCode, 0, "Response Code = " + response.code()).sendToTarget();
}
} catch (Exception e) {
Log.e(TAG, " -=-=- onResponse: ", e);
handler.obtainMessage(REQUEST_FAILED, hashCode, 0, "APIManager Error -> " + e.getMessage()).sendToTarget();
} finally {
requestMap.clear();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, " -=-=- onFailure: ", t);
handler.obtainMessage(REQUEST_FAILED, hashCode, 0, t.getMessage()).sendToTarget();
requestMap.clear();
}
});
return responseBodyCall;
}
检查返回的数据
// 检查是否需要重新登录
private boolean checkIsReLogin(String body) {
if (body.equals("logout")) {
handler.obtainMessage(REQUEST_RELOGIN).sendToTarget();
return true;
} else {
return false;
}
}
// 检查服务器是否成功返回数据
private boolean checkIsSuccess(String body, int hashCode) {
SuccessFailedEntity loginEntity = new Gson().fromJson(body, SuccessFailedEntity.class);
if (loginEntity.getLoginReturnWarnMsg() != null) {
if (loginEntity.getLoginReturnWarnMsg().equals("success")) {
return true;
} else if (loginEntity.getLoginReturnWarnMsg().equals("NoPermission")) {
handler.obtainMessage(REQUEST_SUCCESS_FALSE, "没有权限").sendToTarget();
return false;
}
}
JsonObject jsonObject = new JsonParser().parse(body).getAsJsonObject();
JsonElement successStr = jsonObject.get("success");
if (successStr == null) successStr = jsonObject.get("Success");
if (successStr == null) {
if (loginEntity.getLoginReturnWarnMsg().equals("UserNameOrPwdError")) {
handler.obtainMessage(REQUEST_FAILED, hashCode, 0, "用户名或密码错误").sendToTarget();
} else {
handler.obtainMessage(REQUEST_FAILED, hashCode, 0, loginEntity.getLoginReturnWarnMsg()).sendToTarget();
}
return false;
}
if (successStr != null) {
if (successStr.toString().equals("\"false\"") || successStr.toString().equals("false")) {
SuccessFailedEntity successEntity = new Gson().fromJson(body, SuccessFailedEntity.class);
Log.e(TAG, " -=-=- checkIsSuccess: 数据请求失败:" + successEntity);
String msg = successEntity.getReturnMsg() == null ? successEntity.getMsg() : successEntity.getReturnMsg();
if (msg != null && !msg.isEmpty()) {
handler.obtainMessage(REQUEST_SUCCESS_FALSE, hashCode, 0, msg).sendToTarget();
} else {
handler.obtainMessage(REQUEST_SUCCESS_FALSE, hashCode, 0, "没有错误信息").sendToTarget();
}
return false;
}
return true;
} else {
handler.obtainMessage(REQUEST_SUCCESS_FALSE, hashCode, 0, "返回数据没有 Success 标识").sendToTarget();
}
return false;
}
handler+回传接口返回retrofit请求结果
定义RequestIsSuccess回传接口,在设计业务逻辑接口传入,实现在界面回调得到请求数据和结果
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
RequestIsSuccess requestIsSuccess = requestInterfMap.get(msg.arg1);
Log.d("APIManager", " -=-=- handleMessage: what:" + msg.what +
" requestIsSuccess:" + requestIsSuccess);
if (msg.what != REQUEST_RELOGIN && requestIsSuccess == null) return;
switch (msg.what) {
case REQUEST_SUCCESS_TRUE:
requestIsSuccess.isSuccess(true, true, msg.obj + "");
break;
case REQUEST_SUCCESS_FALSE:
requestIsSuccess.isSuccess(true, false, msg.obj + "");
break;
case REQUEST_FAILED:
requestIsSuccess.isSuccess(false, false, msg.obj + "");
break;
case REQUEST_RELOGIN:
requestReLogin("登陆信息过期!请重新登陆!");
break;
}
}
};
public interface RequestIsSuccess {
void isSuccess(boolean isRequestSuccess, boolean isSuccess, String msg);
}
在业务逻辑接口RequestIsSuccess回调使用的示例
// 定义业务逻辑接口
public Call<ResponseBody> uploadFile(String path, int fileType, RequestIsSuccess requestIsSuccess) {
if (!checkIpPort()) return null;
return request(requestIsSuccess, BroadManageController, uploadFile, path, fileType);
}
// 发起retrofit请求
private Call<ResponseBody> request(RequestIsSuccess requestIsSuccess, String path, String apiPath, Object... objects) {
requestMap.clear();
int hashCode = requestIsSuccess.hashCode();
requestInterfMap.put(hashCode, requestIsSuccess);
switch (path + apiPath) {
case BroadManageController + uploadFile:
requestMap.put(Config.pathParam, objects[0]);
requestMap.put(Config.fileTypeParam, objects[1]);
break;
...
}
return retrofitEnqueue(hashCode, path, apiPath, apiInterface.request(path, apiPath, requestMap));
}
在UI界面调用接口返回数据
APIManager.getInstance().uploadFile(path, fileType, (isRequestSuccess, isSuccess, msg) -> {
Log.d("BroadCreateModel", " -=-=- getMediaIdEbmid: isRequestSuccess:"
+ isRequestSuccess + " isSuccess:" + isSuccess + " msg:" + msg);
if (isRequestSuccess && isSuccess) {
requestListener.callBack(new Gson().fromJson(msg, UploadMediaEntity.class));
} else {
requestListener.callBack(null);
}
});
public interface RequestListener {
void callBack(Object o);
}
多文件上传的接口
主要是请求接口设计现需要传入参数@Body MultipartBody multipartBody
,其次在构造请求体时使用MediaType.parse指名是什么格式文件。
public APIManager uploadDataCollectFile(String areaIds, List<File> fileList, RequestIsSuccess requestIsSuccess) {
String userName = SPUtils.getInstance().getString(SpConfig.USER_NAME);
Log.d(TAG, "uploadDataCollectFile() areaIds:" + areaIds + ", userName:" + userName);
if (!checkIpPort()) return this;
int hashCode = requestIsSuccess.hashCode();
requestInterfMap.put(hashCode, requestIsSuccess);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
RequestBody requestBody;
String parse = "";
for (File file : fileList) {
uploadAudioFileMimeType(file.getName(), parse);
uploadVideoFileMimeType(file.getName(), parse);
if (file.getName().endsWith(".txt")) parse = "text/plain";
requestBody = RequestBody.create(MediaType.parse(parse), file);
builder.addFormDataPart("resource", file.getName(), requestBody);
}
builder.addFormDataPart("userName", userName);
builder.addFormDataPart("areaIds", areaIds);
MultipartBody multipartBody = builder.build();
retrofitEnqueue(hashCode, UpCommandResourceController, add,
apiInterface.uploadFiles(UpCommandResourceController, add, multipartBody));
return this;
}
public boolean checkIpPort() {
boolean checkIP = Utils.checkIPAndPort(BASE_URL);
// TODO BaseURL为空,需要重新登陆
if (!checkIP) {
Log.e(TAG, " -=-=- checkIpPort: IP错误!重新登陆!IP:" + BASE_URL + " isTrue:" + checkIP);
requestReLogin("IP 信息异常,请重新登陆");
}
return checkIP;
}
Utils检查IP的接口
private static final String PREFIX_PATTERN = "((http://)|(https://))";
private static final String IP_FULL_PATTERN =
"(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])"+"\\." +
"(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])" + "\\." +
"(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])" + "\\." +
"(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])";
private static final String PORT_PATTERN = "([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{4}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])";
public static boolean checkIPAndPort(String ipAndPort) {
String pattern = PREFIX_PATTERN + IP_FULL_PATTERN + ":" + PORT_PATTERN;
return ipAndPort.matches(pattern);
}