okhttp3简单封装GET和POST请求工具类
来源:互联网 发布:2016网络小说知乎50 编辑:程序博客网 时间:2024/05/20 06:31
简单封装了okhttp3的工具类以便于以后直接拿来使用。
使用的okhttp版本为:
compile 'com.squareup.okhttp3:okhttp:3.8.1'
该工具类的功能如下:
- Get请求,同步方式获取网络数据
- Post请求,同步方式获取数据
- Get请求,异步方式获取网络数据
- Post请求,异步方式获取数据
- 支持HTTPS请求,自动跳过证书验证
- 判断当前网络是否可用
其中Post请求提交的是键值对<String,String>
1. 完整代码
import android.content.Context;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.util.Log;import java.io.IOException;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.Iterator;import java.util.Map;import java.util.concurrent.TimeUnit;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import okhttp3.Call;import okhttp3.Callback;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;/** * Created by fxjzzyo on 2017/7/12. */public class NetUtils { private static final byte[] LOCKER = new byte[0]; private static NetUtils mInstance; private OkHttpClient mOkHttpClient; private NetUtils() { okhttp3.OkHttpClient.Builder ClientBuilder=new okhttp3.OkHttpClient.Builder(); ClientBuilder.readTimeout(20, TimeUnit.SECONDS);//读取超时 ClientBuilder.connectTimeout(6, TimeUnit.SECONDS);//连接超时 ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//写入超时 //支持HTTPS请求,跳过证书验证 ClientBuilder.sslSocketFactory(createSSLSocketFactory()); ClientBuilder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); mOkHttpClient=ClientBuilder.build(); } /** * 单例模式获取NetUtils * @return */ public static NetUtils getInstance() { if (mInstance == null) { synchronized (LOCKER) { if (mInstance == null) { mInstance = new NetUtils(); } } } return mInstance; } /** * get请求,同步方式,获取网络数据,是在主线程中执行的,需要新起线程,将其放到子线程中执行 * @param url * @return */ public Response getDataSynFromNet(String url) { //1 构造Request Request.Builder builder = new Request.Builder(); Request request=builder.get().url(url).build(); //2 将Request封装为Call Call call = mOkHttpClient.newCall(request); //3 执行Call,得到response Response response = null; try { response = call.execute(); } catch (IOException e) { e.printStackTrace(); } return response; } /** * post请求,同步方式,提交数据,是在主线程中执行的,需要新起线程,将其放到子线程中执行 * @param url * @param bodyParams * @return */ public Response postDataSynToNet(String url,Map<String,String> bodyParams) { //1构造RequestBody RequestBody body=setRequestBody(bodyParams); //2 构造Request Request.Builder requestBuilder = new Request.Builder(); Request request = requestBuilder.post(body).url(url).build(); //3 将Request封装为Call Call call = mOkHttpClient.newCall(request); //4 执行Call,得到response Response response = null; try { response = call.execute(); } catch (IOException e) { e.printStackTrace(); } return response; } /** * 自定义网络回调接口 */ public interface MyNetCall{ void success(Call call, Response response) throws IOException; void failed(Call call, IOException e); } /** * get请求,异步方式,获取网络数据,是在子线程中执行的,需要切换到主线程才能更新UI * @param url * @param myNetCall * @return */ public void getDataAsynFromNet(String url, final MyNetCall myNetCall) { //1 构造Request Request.Builder builder = new Request.Builder(); Request request=builder.get().url(url).build(); //2 将Request封装为Call Call call = mOkHttpClient.newCall(request); //3 执行Call call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { myNetCall.failed(call,e); } @Override public void onResponse(Call call, Response response) throws IOException { myNetCall.success(call,response); } }); } /** * post请求,异步方式,提交数据,是在子线程中执行的,需要切换到主线程才能更新UI * @param url * @param bodyParams * @param myNetCall */ public void postDataAsynToNet(String url, Map<String,String> bodyParams, final MyNetCall myNetCall) { //1构造RequestBody RequestBody body=setRequestBody(bodyParams); //2 构造Request Request.Builder requestBuilder = new Request.Builder(); Request request = requestBuilder.post(body).url(url).build(); //3 将Request封装为Call Call call = mOkHttpClient.newCall(request); //4 执行Call call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { myNetCall.failed(call,e); } @Override public void onResponse(Call call, Response response) throws IOException { myNetCall.success(call,response); } }); } /** * post的请求参数,构造RequestBody * @param BodyParams * @return */ private RequestBody setRequestBody(Map<String, String> BodyParams){ RequestBody body=null; okhttp3.FormBody.Builder formEncodingBuilder=new okhttp3.FormBody.Builder(); if(BodyParams != null){ Iterator<String> iterator = BodyParams.keySet().iterator(); String key = ""; while (iterator.hasNext()) { key = iterator.next().toString(); formEncodingBuilder.add(key, BodyParams.get(key)); Log.d("post http", "post_Params==="+key+"===="+BodyParams.get(key)); } } body=formEncodingBuilder.build(); return body; } /** * 判断网络是否可用 * @param context * @return */ public static boolean isNetworkAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) { } else { //如果仅仅是用来判断网络连接 //则可以使用cm.getActiveNetworkInfo().isAvailable(); NetworkInfo[] info = cm.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; } /** * 生成安全套接字工厂,用于https请求的证书跳过 * @return */ public SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory ssfFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom()); ssfFactory = sc.getSocketFactory(); } catch (Exception e) { } return ssfFactory; } /** * 用于信任所有证书 */ class TrustAllCerts implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}
2. 用法举例
推荐使用异步请求,因为已经把网络请求自动放到子线程了,用起来稍简单。而同步请求还需要自己new Thread+handler来做,几乎和原始的网络请求没区别了。因此这里举例就只举异步请求了。
异步GET请求
点击按钮登录
public void login(View view) { final String account = etAccount.getText().toString(); final String pass = etPassword.getText().toString(); if (account.isEmpty() || pass.isEmpty()) { Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show(); return; } if(!Global.isNetAvailable) { Toast.makeText(this, "网络不可用!", Toast.LENGTH_SHORT).show(); return; } //进度条 loginProgress.setVisibility(View.VISIBLE); //获取网络工具类实例 NetUtils netUtils = NetUtils.getInstance(); //请求网络,一句代码搞定 netUtils.getDataAsynFromNet(Global.LOGIN + "?username=" + account + "&password=" + pass, new NetUtils.MyNetCall() { @Override public void success(Call call, Response response) throws IOException { Log.i("tag", "success"); String result = response.body().string(); final ResponseBean responseBean = JSON.parseObject(result, ResponseBean.class); if (responseBean != null) { runOnUiThread(new Runnable() { @Override public void run() { loginProgress.setVisibility(View.GONE); String errcode = responseBean.getErrcode(); if (errcode.equals("0")) {//登录成功 //记录学号 Global.account = account; //存储用户名密码 saveUserName(account, pass); Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); LoginActivity.this.finish(); } else { Toast.makeText(LoginActivity.this, "请求失败!错误代码: " + errcode, Toast.LENGTH_SHORT).show(); } } }); } } @Override public void failed(Call call, IOException e) { Log.i("tag", "failed"); runOnUiThread(new Runnable() { @Override public void run() { loginProgress.setVisibility(View.GONE); Toast.makeText(LoginActivity.this, "请求失败!", Toast.LENGTH_SHORT).show(); } }); } } ); }
异步POST请求
点击按钮,提交数据
public void postSelect() { //确保选择了楼号 if (tvTargetBuilding.getText().toString().isEmpty()) { Toast.makeText(getActivity(),"请选择楼号!",Toast.LENGTH_SHORT).show(); return; } //构造请求参数 Map<String, String> reqBody = new ConcurrentSkipListMap<>(); reqBody.put("num", "1"); reqBody.put("stuid", Global.account); reqBody.put("buildingNo", selectBuilding + ""); //获取网络请求工具类实例 NetUtils netUtils = NetUtils.getInstance(); //提交数据 netUtils.postDataAsynToNet(Global.SELECT_ROOM, reqBody, new NetUtils.MyNetCall() { @Override public void success(Call call, Response response) throws IOException { Log.i("tag", "success"); String result = response.body().string(); Log.i("tag", "result: " + result); //解析数据 JSONObject jsonObject1 = JSON.parseObject(result); if (jsonObject1 != null) { final int error_code = jsonObject1.getIntValue("error_code"); getActivity().runOnUiThread(new Runnable() { @Override public void run() { Log.i("tag", "errcode: " + error_code); if (error_code == 0) {//提交成功 Toast.makeText(getActivity(), "选择成功!", Toast.LENGTH_SHORT).show(); //跳转到selectSuccessfragment MainActivity.mainActivityInstance.switchFragment(getParentFragment(),SelectSuccessFragment.newInstance("", "")); } else { Toast.makeText(getActivity(), "选择失败!错误代码: " + error_code, Toast.LENGTH_SHORT).show(); } } }); } } @Override public void failed(Call call, IOException e) { Log.i("tag", "failed"); getActivity().runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getActivity(), "请求失败!", Toast.LENGTH_SHORT).show(); } }); } }); }
什么?还嫌代码太长?
其实很短的,除去注释和打印的日志以及一些不相干的部分(我这里的是一个实际的项目,所以涉及到一些其他的东西),你会发现代码很少,核心的代码就是一句。(这时候你可能要说,哼,是一句,但一句有十多行。。。拜托~不要那么懒啦好不好 -_-|||)
要注意的是获取数据后,更新UI要在主线程中。我这里使用的是runOnUiThread
也可以用Handler。
用Handler后你会发现这一部分的代码很少了,因为只需要把获取的数据用Message发送到Handler处理就好了,这样就把代码分散开了
用runOnUiThread
的好处是很直接,不过看起来代码都堆到一起,其实很方便的。
完结,撒花~
阅读全文
0 0
- okhttp3简单封装GET和POST请求工具类
- swift3.0请求https封装工具类(get请求和post请求)
- Volley中的GET和POST请求工具库的封装
- ASIHTTPRequest 对GET和POST请求简单封装
- 简单封装Http的Get和Post请求
- 简单封装ajax的get和post请求
- 对OkHttp3的单独封装 get和post
- Apache 大三方法HTTP请求链接响应之HttpClient的GET和POST工具类封装
- ASIHTTPRequest 对GET POST 请求简单封装
- 【andorid】基于okhttp3网络请求帮助类(GET、POST)
- Java学习笔记———《http的get请求和post请求及封装的工具类》
- HttpClientUtil工具类,发送get请求和post请求
- java工具类-------get请求和post请求
- java封装get和post请求
- Android-封装post和get 网络请求
- AFNetWorking GET 和 POST请求 封装
- post和get请求具体代码封装
- 封装GET、POST请求
- 关于Java script 定时器(timer)的一些使用
- 学习记录6
- spfa和广度优先遍历
- 12月9日的学习报告--定时器
- 集群部署时,session缓存问题
- okhttp3简单封装GET和POST请求工具类
- NFS服务的配置与应用
- 最小生成树模版题Prim——修建道路
- 利用json-lib给前台传递json数据
- Servlet实现文件上传的原理
- 编译原理——短语、直接短语、句柄
- 【51nod1792】Jabby's segment tree
- OpenStack API 初探(调用API获取OpenStack信息)
- 1137. Final Grading (25)