前言:应用程序需要发送网络请求服务器的接口,可使用OkHttp 3发送请求获取服务端数据
GitHut地址

Step 1:申请网络请求的权限:在manifests层的AndroidManifest.xml里的
<manifest控件里添加:

    <!--允许程序打开网络套接字--><uses-permission android:name="android.permission.INTERNET" />

Step 2:引入依赖:在Gradle Scripts层的build.gradle(Module:app)里的dependencies 里添加:然后点击右上角的Sync Now下载,等待下载完成

    //网络请求implementation 'com.squareup.okhttp3:okhttp:4.4.0'//打印网络日志implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0'

Step 3:新建一个OkHttpTool工具类(此为施老师的):

package com.gx.hotel.util;//该工具类的包路径,根据自己路径修改import android.util.Log;import androidx.annotation.NonNull;import java.io.File;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;/*** create by qzlysxj* Fix bu qzlysxj on 2020-2-26* <p>* 便于使用okhttp3的工具类*/
public class OkHttpTool {//日志标志private static String TAG = "OkHttpTool";//OkHttpClient类private static final OkHttpClient myOkHttpClient;static {//========日志拦截器=========//Log拦截器HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {@Overridepublic void log(@NonNull String message) {Log.i(TAG, message);}});//设置日志显示级别HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;loggingInterceptor.setLevel(level);//========cookie处理--让服务端记住app//这里是设置cookie的,但是并没有做持久化处理;只是把cookie保存在内存中CookieJar cookieJar=new CookieJar() {private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();//保存cookie@Overridepublic void saveFromResponse(@NonNull HttpUrl url, @NonNull List<Cookie> cookies) {cookieStore.put(url.host(), cookies);}//获取cookie@Overridepublic List<Cookie> loadForRequest(@NonNull HttpUrl url) {List<Cookie> cookies = cookieStore.get(url.host());return cookies != null ? cookies : new ArrayList<Cookie>();}};//创建OkHttpClientmyOkHttpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS)//连接超时.writeTimeout(60, TimeUnit.SECONDS)//写入超时.readTimeout(60, TimeUnit.SECONDS)//读取超时.addInterceptor(loggingInterceptor)//添加日志处理拦截器.cookieJar(cookieJar).build();}//================对外方法=====================/*** Get 请求* @param url{String} 请求地址* @param parameters{Map<String, Object>} 请求参数* @param responseCallback{ResponseCallback} 请求回调*/@SuppressWarnings("unused")public static void httpGet(String url, Map<String, Object> parameters, ResponseCallback responseCallback) {Request request = createGetRequest(url, parameters);doRequest(request, responseCallback);}/*** POST 请求* @param url{String} 请求地址* @param parameters{Map<String, Object>} 请求参数* @param responseCallback{ResponseCallback} 请求回调*/public static void httpPost(String url, Map<String, Object> parameters, ResponseCallback responseCallback) {Request request = createPostRequest(url, parameters);doRequest(request, responseCallback);}/*** POST 请求 JSON格式参数* @param url{String} 请求地址* @param json{String} JSON格式参数* @param responseCallback{ResponseCallback} 请求回调*/@SuppressWarnings("unused")public static void httpPostJson(String url, String json, ResponseCallback responseCallback) {Request request = createPostRequestJson(url, json);doRequest(request, responseCallback);}/*** POST 请求 文件上传* @param url{String} 请求地址* @param parameters{Map<String, Object>} 请求参数* @param files{Map<String, File>} 上传的文件列表* @param responseCallback{ResponseCallback} 请求回调*/@SuppressWarnings("unused")public static void httpPostWithFile(String url, Map<String, Object> parameters, Map<String, File> files, ResponseCallback responseCallback) {Request request = createPostRequestWithFile(url, parameters, files);doRequest(request, responseCallback);}/*** POST 请求 文件上传 byte数组* @param url{String} 请求地址* @param parameters{Map<String, Object>} 请求参数* @param files{Map<String, byte[]>}上传的文件列表* @param responseCallback{ResponseCallback} 请求回调*/@SuppressWarnings("unused")public static void httpPostWithFileByte(String url, Map<String, Object> parameters, Map<String, byte[]> files, ResponseCallback responseCallback) {Request request = createPostRequestWithFileByte(url, parameters, files);doRequest(request, responseCallback);}//=====回调接口======public interface ResponseCallback {void onResponse(boolean isSuccess, int responseCode, String response, Exception exception);}//===========私有方法===============//====构建请求====//构建 Get请求private static Request createGetRequest(String url, Map<String, Object> parameters) {StringBuilder urlBuilder = new StringBuilder();urlBuilder.append(url);if (url.indexOf('?') <= -1) {//未拼接参数urlBuilder.append("?");}for (Map.Entry<String, Object> entry : parameters.entrySet()) {urlBuilder.append("&");urlBuilder.append(entry.getKey());urlBuilder.append("=");urlBuilder.append(entry.getValue().toString());}return getBaseRequest().url(urlBuilder.toString()).build();}//构建 POST 请求private static Request createPostRequest(String url, Map<String, Object> parameters) {@SuppressWarnings("all")FormBody.Builder builder = new FormBody.Builder(Charset.forName("UTF-8"));if (parameters != null) {for (Map.Entry<String, Object> entry : parameters.entrySet()) {builder.add(entry.getKey(), entry.getValue().toString());}}FormBody formBody = builder.build();return getBaseRequest().url(url).post(formBody).build();}//构建 POST JSON格式参数请求private static Request createPostRequestJson(String url, String json) {MediaType mediaType = MediaType.parse("application/json;charset=utf-8");RequestBody body = RequestBody.create(json,mediaType);return getBaseRequest().url(url).post(body).build();}//构建 POST带文件的 请求private static Request createPostRequestWithFile(String url, Map<String, Object> parameters, Map<String, File> files) {// form 表单形式上传MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);if (files != null) {for (Map.Entry<String, File> fileEntry : files.entrySet()) {File file = fileEntry.getValue();if (file != null) {// MediaType.parse() 里面是上传的文件类型。RequestBody body = RequestBody.create(file,MediaType.parse("application/octet-stream"));String filename = file.getName();// 参数分别为, 请求key ,文件名称 , RequestBodyrequestBody.addFormDataPart(fileEntry.getKey(), filename, body);}}}if (parameters != null) {// map 里面是请求中所需要的 key 和 valuefor (Map.Entry<String, Object> entry : parameters.entrySet()) {String key = entry.getKey();String value = entry.getValue().toString();requestBody.addFormDataPart(key, value);}}return getBaseRequest().url(url).post(requestBody.build()).build();}//构建 POST带文件的 请求private static Request createPostRequestWithFileByte(String url, Map<String, Object> parameters, Map<String, byte[]> files) {// form 表单形式上传MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);if (files != null) {for (Map.Entry<String, byte[]> fileEntry : files.entrySet()) {byte[] file = fileEntry.getValue();if (file != null) {// MediaType.parse() 里面是上传的文件类型。RequestBody body = RequestBody.create(file,MediaType.parse("application/octet-stream"));// 参数分别为, 请求key ,文件名称 , RequestBodyrequestBody.addFormDataPart(fileEntry.getKey(), fileEntry.getKey(), body);}}}if (parameters != null) {// map 里面是请求中所需要的 key 和 valuefor (Map.Entry<String, Object> entry : parameters.entrySet()) {String key = entry.getKey();String value = entry.getValue().toString();requestBody.addFormDataPart(key, value);}}return getBaseRequest().url(url).post(requestBody.build()).build();}//===实际进行请求的方法private static void doRequest(final Request request, final ResponseCallback responseCallback) {//使用okhttp3的异步请求myOkHttpClient.newCall(request).enqueue(new Callback() {//失败回调@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {//回调responseCallback.onResponse(false, -1, null, e);//用于输出错误调试信息if (e.getMessage()!=null){Log.e(TAG, e.getMessage());}}//成功回调@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {int responseCode = response.code();//获取响应码ResponseBody responseBody = response.body();//获取 ResponseBodyif (response.isSuccessful() && responseBody != null) {String strResponse = responseBody.string();//回调responseCallback.onResponse(true, responseCode, strResponse, null);} else {//回调responseCallback.onResponse(false, responseCode, null, null);}}});}//获取请求 指定client为Androidprivate static Request.Builder getBaseRequest() {Request.Builder builder = new Request.Builder();builder.addHeader("client", "Android");return builder;}
}//.addInterceptor(new Interceptor() {//    @Override
//    public Response intercept(@NonNull Chain chain) throws IOException {//        Request request = chain.request().newBuilder()
//            .addHeader("Connection", "close").build();
//        return chain.proceed(request);
//    }
//})/*以前自己写的日志拦截器*/
//添加日志处理拦截器
//.addInterceptor(new Interceptor() {//    @Override
//    public Response intercept(@NonNull Chain chain) throws IOException {//        Request request = chain.request();
//        long startTime = System.currentTimeMillis();
//        Response response = chain.proceed(chain.request());
//        long endTime = System.currentTimeMillis();
//        long duration = endTime - startTime;
//        MediaType mediaType = response.body().contentType();
//        String content = response.body().string();
//        Log.d(TAG, "\n");
//        Log.d(TAG, "----------Start----------------");
//        Log.d(TAG, "| " + request.toString());
//        String method = request.method();
//        if ("POST".equals(method)) {//            StringBuilder sb = new StringBuilder();
//            if (request.body() instanceof FormBody) {//                FormBody body = (FormBody) request.body();
//                for (int i = 0; i < body.size(); i++) {//                    sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");
//                }
//                if (sb.length() > 0) {//                    //在参数不为空的情况下处理最后的 “,”
//                    sb.delete(sb.length() - 1, sb.length());
//                }
//                Log.d(TAG, "| RequestParams:{" + sb.toString() + "}");
//            }
//        }
//        Log.d(TAG, "| Response:" + content);
//        Log.d(TAG, "----------End:" + duration + "毫秒----------");
//        //由于前面的代码已经获取了响应结果,会导致后续代码无法获取到响应结果
//        // 需要重新构建一个响应结果并返回
//        return response.newBuilder()
//                .body(ResponseBody.create(mediaType, content))
//                .build();
//    }
//})

ps:因为Android P系统限制了明文流量的网络请求,所以需要配置一下文件,具体如下:
查看自己的笔记(解决Android P系统限制了明文流量的网络请求) 或 查看该地址:地址

使用方法:

第一种:带参数或不带参数的:

 /**访问服务器方法路径(ps :本人后台是ssm项目的,所以路径要根据自己的项目框架而定)!路径的结构:手机调试,路径为(ps:电脑和手机要连同一网络):http://+电脑网络的IPv4地址+/+项目名+/+控制器+/+方法例:String url="http://192.168.43.9:8080/CarTaketing/User/ifLoginSure.do";//也可以在这拼接参数虚拟机调试,不用连接网络:http://10.0.2.2:8080/+项目名称+/+控制器+/+方法例:String url="http://10.0.2.2:8080/CarTaketing/User/ifLoginSure.do";ps:如果用虚拟机调试,电脑连接wifi,可以用手机调试那种路径,虚拟机不用连接wifi*/String url="http://192.168.43.9:8080/CarTaketing/User/ifLoginSure.do";//也可以在这拼接参数//添加参数,设置值(参数名  和  接受类型要和 服务端一致,详细请看 下面的注释(这个注释:说明找不到服务器的这个方法(url)))Map<String,Object> map=new HashMap<>();map.put("name","liang");map.put("password","456");//==发送请求        ps:若不需要参数,参数2 的这个map可以为null//参数1为访问服务器的地址,参数2为map类型,里面有各个参数名和对应的值,参数3为发送网络后执行的回调,不管成功否都会执行OkHttpTool.httpPost(url, map, new OkHttpTool.ResponseCallback() {//isSuccess:值false为发送失败,true为成功;responseCode:值为200为发送成功,否则为失败;response:发送成功后,服务端返回的数据@Overridepublic void onResponse(final boolean isSuccess, final int responseCode, final String response, Exception exception) {//发送后,对当前的Activity的布局做出反应(如,弹出提示,对布局的更改),就得在该activity的ui线程上执行,若不需要,则不用在该ui线程上执行。MainActivity.this.runOnUiThread(new Runnable() {@Overridepublic void run() {if(isSuccess&&responseCode==200){//==说明访问到服务器的方法了  然后就可以对服务器返回的数据(即response)进行相关的操作/**解析服务器返回的数据(即response)说明:因为服务器返回的是json格式的字符串,所以要解析:ps.这里用的是alibaba的fastjson来解析,引入依赖://fastjsonimplementation 'com.alibaba:fastjson:1.2.68'一般来说,服务器把数据转为json前的原来数据是 List集合、bean类(po或vo类)、或数据类型(例:int ,boolea..等等八种)、或String类型,所以解析后的数据就要对应的类型接收。这里罗列出它们各种类型的接受方式:1.List集合类型:    SelectOption为list的类型参数,要与服务端里的list的类型参数对应,解析接收如下:List<SelectOption> data=JSON.parseArray(response,SelectOption.class);2.bean类(po或vo类):2.1:如果是普通的bean类:例如:Message类,里面有属性:int code、String text 和它两的getset方法:解析接收如下:Message message = JSON.parseObject(response, Message.class);2.2:如果是bean类带有类型参数的话,例如:Bsgrid<T>类,里面有属性:int curPage、int totalRows、boolean success、List<T> data 和  它们的getset方法,那解析接收如下:Bsgrid<CarCheckVo> bsgrid=JSON.parseObject(response,new TypeReference<Bsgrid<CarCheckVo>>(){});ps:CarCheckVo是一个bean类,要与服务器里的类型参数一致。3.八种类型或String类型:用String类型举例解析:String str=JSON.parseObject(response, String.class);*///这里是一个普通的bean类型Message message = JSON.parseObject(response, Message.class);Toast.makeText(MainActivity.this,message.getText(),Toast.LENGTH_LONG).show();}else{/**说明找不到服务器的这个方法(url),原因:** 1.服务器的 路径(请求的方法路径) 和 这个 url(请求的方法路径) 是不是一致;* 2.这个服务器方法的形参名,是否和 map 里的 各个key名字 是否对应;* 3.这个服务器方法的形参接受的类型,是否和 map 里的 各个key值的接受类型 是否对应;*//**举例:服务器的方法:@RequestMapping(value = "ifLoginSure",produces = AJSON_UTF8)public String ifLoginSure(String name,String password)错误1,路径方法名没写对:http://192.168.43.9:8080/CarTaketing/User/ifLo5555ginS.do错误2,形参名不对应:map.put("namessss","liang");  形参名是name,map添加的是namessss,不对应错误3,接受类型不对应:map.put("name",1111);       方法的形参的name 的接受类型是String,却传的是int类型,不对应,这个错误很容易犯,比如字符串的date,接受的是date类型,再如,形参类型是int  ,传过来的是null,则无法接受,报错!!*/Toast.makeText(MainActivity.this,"连接服务器失败,请稍后重试!",Toast.LENGTH_LONG).show();}}});}});

第二种:带有文件上传:

   //服务器方法路径String url= ServiceUtil.getUserUrl("uploadMemberPicture");//Object类型的参数集Map<String,Object> map=new HashMap<>();map.put("memberId",myApplication.getUserBean().getUserid());//文件类型的参数集Map<String,File> fileMap=new HashMap<>();fileMap.put("photo", fileUp);//ps:服务器接收类型记得是File类型哦,//例:public Object uploadMemberPicture(int memberId,@RequestParam(value="photo")MultipartFile mPhoto)//注解:   @RequestParam(value="photo")  里的  photo  对应 fileMap.put("photo", fileUp);里的 photo  //(ps:因是ssm项目,所以是这样写,实际根据自己项目框架写)//参数1为服务器路径、2为Object类型的参数集、3为文件类型的参数集OkHttpTool.httpPostWithFile(url, map, fileMap, new OkHttpTool.ResponseCallback() {@Overridepublic void onResponse(final boolean isSuccess,final int responseCode, final String response, Exception exception) {MainActivity.this.runOnUiThread(new Runnable() {@Overridepublic void run() {         //这里的代码内容同第一种}});}});

更多方法请查看OkHttpTool的工具类源码!!

OkHttp3 发送网络请求服务器相关推荐

  1. vue如何发送网络请求,使用axios事半功倍!

    目录 一.axios使用 1.支持多种请求方式: 2.安装 3.简单使用实例 4.发送并发请求 5.全局配置 二.axios的实例 1.为什么要创建 axios的实例呢? 2.使用 三..axios模 ...

  2. Fetch发送网络请求

    1. 文档 https://github.github.io/fetch/ https://segmentfault.com/a/1190000003810652 2. 特点 fetch: 原生函数, ...

  3. axios发送网络请求

    网络模块封装 选择什么网络模块 传统的Ajax 缺点:配置和调用方式等非常混乱 jQuery-Ajax 缺点:在Vue整个开发中都是不需要使用jQuery的 axios axios 功能特点: 在浏览 ...

  4. python 网络接口 开发_Python自动化学习笔记(八)——接口开发、发送网络请求、发送邮件、写日志...

    1.接口开发(flask模块) Python自动化学习笔记(七)接口开发部分的内容补充 1.1参数为json格式: flask.request.is_json #判断参数是否是json格式 flask ...

  5. Python自动化学习笔记(八)——接口开发、发送网络请求、发送邮件、写日志...

    1.接口开发(flask模块) Python自动化学习笔记(七)接口开发部分的内容补充 1.1参数为json格式: flask.request.is_json #判断参数是否是json格式 flask ...

  6. 网络编程-JavaScript中发送网络请求汇总

    文章目录 1.前后端分离优势 2.HTTP协议的解析 2.1 HTTP的介绍 2.2 HTTP的组成 2.3 HTTP的版本 2.4 HTTP请求方式 2.5 HTTP请求头字段 2.6 HTTP响应 ...

  7. 微信小程序Api发送网络请求(request)

    微信小程序发送网络请求(request) 下边的地址是微信小程序开发平台对网络请求的介绍. 微信小程序网络请求介绍 最近公司要求开发小程序,下面是我查看微信小程序文档,写的一个demo,记录下来方便以 ...

  8. 微信小程序中发送网络请求

    文章目录 小程序项目 app.json pages/index/index.html pages/index/index.wxss pages/index/index.js 发送网络请求 网络请求函数 ...

  9. Python发送网络请求(requests)

    Python发送网络请求(requests) Python已经是广泛使用的脚本语言了,我们可以使用requests库进行网络请求. 在PyPI中搜索requests,就可以找到这个库 1. 安装 pi ...

最新文章

  1. 对函数指针与typedef的理解:typedef void (*sighandler_t)(int)
  2. 普通背包问题-枚举算法(《算法竞赛宝典》 第二部 基础算法艺术)
  3. linux c 写文件 换行符,[Linux文件]带回车换行的写入字符串实例
  4. 11张高清Python全知识地图,强烈建议学习
  5. cadence ic5141安装包_linux下安装cadence ic5141
  6. 鸿蒙系统是电脑还是手机,鸿蒙系统什么时候能用在电脑上,华为鸿蒙系统什么时候能用...
  7. ARCore:ARCore的初体验
  8. CAD格式交换全能:CAD DLL 15.0 Crack
  9. 用Websocket聊天完整demo,做笔记用,各位大佬多多指教
  10. 小型数据库系统开发作业
  11. kettle使用--1.mysql多表关联导入mongoDB
  12. Linux中设置和重启网络的命令
  13. 吉林大学软件学院2021级计算机组成原理期末50道简答题
  14. magento Shopping Cart Price Rule 购物车促销规则
  15. centos安装nagios
  16. Library-Files-维持权限--对比自带CLSID打开程序
  17. python lib error
  18. ug许可证无法连接服务器,NX许可证错误:无法连接至许可证服务器系统。SPLM_LICENSE_SERVER错误[-15]...
  19. 2019FME博客大赛——基于FME和ArcGIS Pro的规划成果标准化建库方法
  20. 安装SSL证书后,解决混合内容造成页面错误提示的处理办法

热门文章

  1. Linux系统监控——top命令
  2. 奇葩的公司,奇葩的现象……
  3. php symfony 安装,安装和设置Symfony框架
  4. scala:查询圆周率pi
  5. 【电力电子技术DC-AC】电流跟踪PWM控制三相逆变器的simulink仿真
  6. 针对乐视网的主页无法打开的解决办法
  7. android软件工程师/android中间件开发
  8. incaseformat蠕虫病毒昨日“发作“,23日可能还会发作
  9. addEvent.js源码解析
  10. 如何Tomcat部署web应用