xUtils3.x的网络请求封装和请求https之单向SSL验证
很久没写博客了, 自己定的路已经走歪,菜鸟的进阶之路上我只是走了一步,自从发了一篇博客之后在没有来过这里,已经有一年了吧,今天再次回到这里。
言归正传,今天要写的是xUtils3.x网络请求的封装和请求https,最近xUtils做出了一次比较大的重构,原有的使用规则都有了新的变化。具体的变化可以去 https://github.com/wyouflf/xUtils3.git ,还有很多大神都整理了很多写了博客,需要了解的自行去看。
xUtils3.x还是和之前一样分有4大模块:注解模块,网络模块,图片加载模块,数据库模块。
在开始封装之前,我们需要把准备工作做好.
1. 不可缺少的权限:
2. 导入jar 和 so 文件 (提供一个大神的下载地址:http://dl.bintray.com/wyouflf/maven/org/xutils/xutils/ )
如果是AS 使用Gradle 构建时添加一下依赖即可 compile 'org.xutils:xutils:3.2.2'
使用Eclipse构建时操作步骤如下: 下载aar文件并使用然后用zip解压, 取出jar包和so文件. 将xutils-3.2.0.jar 以及armeabi添加到工程的libs中即可。
3.初始化 在Application的oncreate方法中加入下面代码:
x.Ext.init(this);
x.Ext.setDebug(BuildConfig.DEBUG);
4.在Acitivity里使用注解的话. 需要在Activity的oncreate方法中加入下面代码:
x.view().inject(this);
Fragment里注解就需要onCreateView里 return x.view().inject(this, inflater, container);
哈哈,是不是太啰嗦了,等等先。 xUtils3.x网络请求里最大的变化就是
x.http().get(params, mCallback); x.http().post(params, mCallback);直接用x来获取。取消了HttpUtils这个类.
RequestParams params = new RequestParams(url); 在newRequestParams的时候必须要传请求接口url. 这就是在网络模块里一些的改变. 但并不是所有的。
开始上代码咯。HttpXUtils3Manager类
<span style="font-weight: normal;">import java.io.InputStream;
import java.net.HttpCookie;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.List;import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;import org.xutils.x;
import org.xutils.common.Callback.Cancelable;
import org.xutils.common.Callback.CommonCallback;
import org.xutils.ex.HttpException;
import org.xutils.http.HttpMethod;
import org.xutils.http.RequestParams;
import org.xutils.http.cookie.DbCookieStore;import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager.NameNotFoundException;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.TypeReference;
import com.lidroid.xutils.http.HttpHandler;
import com.ylpw.ticketapp.BuildConfig;
import com.ylpw.ticketapp.R;
import com.ylpw.ticketapp.YongLeApplication;
import com.ylpw.ticketapp.common.App;
import com.ylpw.ticketapp.common.ConstantManager;
import com.ylpw.ticketapp.common.LogManager;
import com.ylpw.ticketapp.log.Logger;
import com.ylpw.ticketapp.model.TResult;
import com.ylpw.ticketapp.model.TResultWrapper;
import com.ylpw.ticketapp.util.Base64Util;
import com.ylpw.ticketapp.util.NetworkUtils;
import com.ylpw.ticketapp.util.ToastUtils;/*** xUtils3 应用与网络通讯管理类**/
public class HttpXUtils3Manager {/** Https 证书验证对象 */private static SSLContext s_sSLContext = null;private static final String TAG = "HttpXUtils3Manager";private HttpXUtils3Manager() {}/*** http get请求* * @param params 请求参数 get请求使用 addQueryStringParameter方法添加参数* @param mCallback 回调对象* @return 网络请求的Cancelable 可以中断请求*/public static Cancelable getHttpRequest(RequestParams params, final XUtils3Callback mCallback) {return sendHttpRequest(HttpMethod.GET, params, mCallback);}/*** http post请求* * @param params 请求参数 post请求使用 addBodyParameter方法添加参数* @param mCallback 回调对象* @return 网络请求的Cancelable 可以中断请求*/public static Cancelable postHttpRequest(RequestParams params, final XUtils3Callback mCallback) {return sendHttpRequest(HttpMethod.POST, params, mCallback);}/*** 发送请求 Cancelable* * @param method 请求方式(GET POST)* @param params 请求参数* @param mCallback 回调对象* @return 网络请求的Cancelable 可以中断请求*/public static Cancelable sendHttpRequest(HttpMethod method, RequestParams params, final XUtils3Callback mCallback){if (!NetworkUtils.isNetworkAvailable(YongLeApplication.getInstance())) {// 网络请求之前先检查网络是否可用mCallback.onFinished();mCallback.onError(new TResult(), "网络连接失败,请重试");ToastUtils.showToast(R.string.checknetwork);return null;}if (params == null) {params = new RequestParams();}params.setHeader("Cookie", App.getCookie());// 设置Cookieparams.setCacheMaxAge(1000*0); //为请求添加缓存时间params.setConnectTimeout(ConstantManager.CONNECTION_TIME_OUT); //超时时间60s/** Cancelable cancelable = x.http().get(params, Callback); */return x.http().request(method, params , new CommonCallback<String>() {@Override //取消public void onCancelled(CancelledException msg) {ToastUtils.showToast(msg.getMessage());mCallback.onError(new TResult(), msg.getMessage());mCallback.onFinished();}@Override //错误public void onError(Throwable arg0, boolean arg1) {if (arg0 instanceof HttpException) { // 网络错误}ToastUtils.showToast(arg0.getMessage());LogManager.i(TAG, "==> RequestCallBack.onError()");LogManager.e(TAG, "==> response:" + arg0.getMessage() + "\n==> error:" + arg1);mCallback.onError(new TResult(), arg0.getMessage());mCallback.onFinished();}@Override //成功public void onSuccess(String result) {if (result == null) {return;}LogManager.i(TAG, "==> RequestCallBack.onSuccess()");Logger.json(result);try {TResultWrapper<Object> wrapper = JSON.parseObject(result, new TypeReference<TResultWrapper<Object>>() {});TResult mTResult = wrapper.getResult();if (mTResult != null) {switch (mTResult.getCode()) {case 0:// 请求成功返回正常的数据mCallback.onSuccess(result);mCallback.onFinished();// 回调请求结束的方法break;default://这是失败的错误码mCallback.onError(mTResult, mTResult.getMessage());break;}} } catch (JSONException e) {e.printStackTrace();}}@Override //完成public void onFinished() {}});}/*** 中断网络请求* * @param mCancelable Cancelable*/public <T> void interrupt(Cancelable mCancelable) {if (mCancelable != null && !mCancelable.isCancelled()) {mCancelable.cancel();}}}
</span>
公共的请求回调类XUtils3Callback
<span style="font-weight: normal;">import com.ylpw.ticketapp.model.TResult;/*** 公共的请求回调类* * xiexucheng*/
public interface XUtils3Callback {/*** 通讯成功,返回正常的数据时回调的方法* * @param result 返回信息*/void onSuccess(String result);/*** 请求失败、拦截到错误等,回调的方法* * @param mTResult 错误信息 根据自己的项目接口的返回去model* @param message 提示信息*/void onError(TResult mTResult, String message);/*** 请求结束回调的方法*/void onFinished();}</span>
在Activity中使用
private void getHttpXUtilsData() {RequestParams params = new RequestParams("https://www.baidu.com");params.addQueryStringParameter("name", "dlx2cheng"); HttpXUtils3Manager.getHttpRequest(params, new XUtils3Callback() {@Overridepublic void onSuccess(String result) {//这里用的是fastjson解析TResultWrapper<TProductDataWrapper> resulta = JSON.parseObject(result, new Typ<span style="white-space:pre"> </span>eReference<TResultWrapper<TProductDataWrapper>>() {});TProductDataWrapper data = resulta.getData();if (data != null) {}}@Overridepublic void onError(TResult mTResult, String message) {ToastUtils.showToast(message);}@Overridepublic void onFinished() {}});}
到这里基本就是一套xUtils3.x的get和post请求的封装了。 但是.. 如果你运行成功了一定会事情失败。因为请求的是https://www.baidu.com
这是https的请求. 一般公司都有一个SSL证书,也就是crt文件或者cet文件(其实都是一样的)。 把文件放入assets或者raw文件下, 只要拿到文件就行了。
xUtils当然也提供了设置SSL的方法.
params.setSslSocketFactory(sslContext.getSocketFactory()); //绑定SSL证书(https请求)
当然也是写在sendHttpRequest里,跟在设置超时时间后面就行了。 下面看代码:
params.setHeader("Cookie", App.getCookie());// 设置Cookieparams.setCacheMaxAge(1000*0); //为请求添加缓存时间params.setConnectTimeout(ConstantManager.CONNECTION_TIME_OUT); //超时时间60s/** 判断https证书是否成功验证 */SSLContext sslContext = getSSLContext(YongLeApplication.getInstance());if(null == sslContext){if (BuildConfig.DEBUG) LogManager.d(TAG, "Error:Can't Get SSLContext!");return null;}params.setSslSocketFactory(sslContext.getSocketFactory()); //绑定SSL证书(https请求)
这里是验证SSL的方法: 我这里写了官方推荐的和官方不推荐的(信任所有证书). 其实如果用信任所有证书是不安全的和请求http没什么区别.. 所有还是建议官方推荐。
/*** 获取Https的证书* @param context Activity(fragment)的上下文* @return SSL的上下文对象*/private static SSLContext getSSLContext(Context context) {CertificateFactory certificateFactory = null;InputStream inputStream = null;Certificate cer = null;KeyStore keystore = null;TrustManagerFactory trustManagerFactory = null;try {certificateFactory = CertificateFactory.getInstance("X.509");inputStream = context.getAssets().open("baidu.crt");//这里导入SSL证书文件try {//读取证书cer = certificateFactory.generateCertificate(inputStream);LogManager.i(TAG, cer.getPublicKey().toString());} finally {inputStream.close();}//创建一个证书库,并将证书导入证书库keystore = KeyStore.getInstance(KeyStore.getDefaultType());keystore.load(null,null); //双向验证时使用keystore.setCertificateEntry("trust", cer);// 实例化信任库trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());// 初始化信任库trustManagerFactory.init(keystore);s_sSLContext = SSLContext.getInstance("TLS");s_sSLContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());//信任所有证书 (官方不推荐使用)
// s_sSLContext.init(null, new TrustManager[]{new X509TrustManager() {
//
// @Override
// public X509Certificate[] getAcceptedIssuers() {
// return null;
// }
//
// @Override
// public void checkServerTrusted(X509Certificate[] arg0, String arg1)
// throws CertificateException {
//
// }
//
// @Override
// public void checkClientTrusted(X509Certificate[] arg0, String arg1)
// throws CertificateException {
//
// }
// }}, new SecureRandom());return s_sSLContext;} catch (Exception e) {e.printStackTrace();}return null;}
在验证SSL证书的过程中很多人都会出现一个异常:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
这个异常呢也就是说证书的信任路径找不到. 当时我就报了这俩问题, 我仔细看代码没发现问题, 又上某度查了一天还是没有什么答案, 有的都是让信任所有证书,后来我突然想到看证书的有效时间才发现证书到期了!!! 赶紧找公司给了我一个新的, 放进去后完全没事了 - -. 很纠结的。 当然了, 有可能还有其他的问题会导致出现这两个异常。。
如果有发现代码不对和疑问的地方,欢迎各位来探讨. 我的QQ和邮箱:7907716、dlx2cheng@sina.com
xUtils3.x的网络请求封装和请求https之单向SSL验证相关推荐
- vue请求封装,http-接口部分(文档笔记)
http-接口 目录结构 . ├── src 源码目录 │ ├── http 请求封装 │ │ ├── modules 请求所属模块 │ │ │ ├── example.js example模块请求 ...
- HTML封装AJAX请求,在请求里面写登录的逻辑 ajax 网络请求 post
调用方法: 先引用config.js,然后调用封装网络请求. 里面三个参数 1.url, 2.请求需要提交的数据, 3.请求类型 // 获取二维码.背景图片接口 getScheduleInfo() ...
- (iOS-框架封装)AFN3.x 网络请求封装
AFNetworking 我项目里面的网络请求是一外包大牛基于AFN2.x封装的基本网络请求,感觉其封装的贼好,对服务端返回的错误码统一处理,对返回的 json 数据下发给每个继承自基本网络请求的子网 ...
- jq封装post请求数据_GitHub - xiaohange/JQHttpRequest: GET/POST / PUT / DELETE 网络请求的封装...
JQHttpRequest 前言 JQHttpRequest:目前二次封装网络库支持四种请求:GET.POST.PUT.DELETE较常见的请求,HEAD/PATH/COPY/OPTIONS/LINK ...
- java封装拦截请求_Retrofit,OkHttp拦截器,RxJava封装请求网络
Retrofit和Okhttp和RxJava的封装 导入依赖 compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex. ...
- iOS开发-网络-合理封装请求接口
概述 如今大多App都会与网络打交道,作为开发者,合理的对网络后台请求接口进行封装十分重要.本文要介绍的就是一种常见的采用回调函数(方法)的网络接口封装,也算的是一种构架吧. 这个构架主要的idea是 ...
- Spring Boot + Vue 前后端分离开发,前端网络请求封装与配置
前端网络访问,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,网络访问较多的采用 vue-resources,Vue2.0 之后,官方不再建议使用 vue-resources ,这个 ...
- 小程序中封装ajax请求,如何在微信小程序中封装网络请求
如何在微信小程序中封装网络请求 发布时间:2021-05-11 16:59:36 来源:亿速云 阅读:95 作者:Leah 这期内容当中小编将会给大家带来有关如何在微信小程序中封装网络请求,文章内容丰 ...
- 微信小程序开发之——网络请求封装
一 概述 网络请求地址放到url.js中,分别制定开发环境,体验环境,线上环境 网络请求的方法放到request.js中,暴露get.post.upload方法 请求前显示加载中,请求结束后隐藏加载中 ...
最新文章
- 怎样才能学好Vue,听听尤雨溪怎么说?
- 收藏这8个windows神级工具,你的办公效率也会提高
- 提到“子类”和“子类型”是不同的
- c++图形中如何判断鼠标点击在一条直线上_PS教程:十种抠图方法【上】
- vue 获取当前位置 高德_vue高德地图获取当前位置
- 重写setTimeout扩展参数
- PHP ajax跨域问题最佳解决方案
- 硅谷大佬提前剧透未来!6本书,助你走在AI时代前沿
- [Node.js] 模块化 -- 爬虫
- Bootstrap 图片样式
- java冒泡怎么写_java 冒泡 又一种写法
- 生活情景英语:英语国家生存英语精选
- 【UVA1599】Ideal Path理想路径--两种约束条件(!!双向bfs+非简单图的最短路+无向图邻接记录法)
- 【转】Windows下部署Appium教程(Android App自动化测试框架搭建)
- programer2012
- MAC jd-gui 安装
- 数据库身份证号用什么类型_数据库设计规范
- 解决阿里云Workbench登录失败
- 微信打开跳转浏览器php代码,简单通用QQ/微信跳转浏览器打开代码
- Google Sheet 学习笔记
热门文章
- (数字图像处理MATLAB+Python)第四章图像正交变换-第一节:离散傅里叶变换
- android sqlite #039;,问题详情_百度云推送_免费专业最精准的移动推送服务平台
- 电子类专业毕业后到底是做什么的??挺有意义的
- 关于SE54视图簇的创建和维护
- linux vsftp查看ftp账号信息的方法
- 22.裸板--I2C协议
- CSAPP Lab:attacklab
- c语言函数参数的含义,C语言函数的含义
- python同步远程文件夹_python pyinotify 监控远程文件夹来实现即时全量同步
- 解读高端PCB板的设计工艺!