简介
OkHttp是一个高效、现代的HTTP客户端库,专为Android和Java应用程序设计,用于发送网络请求和处理响应。它支持HTTP/2和SPDY协议,允许连接复用,减少延迟,提高网络效率。OkHttp还处理了常见的网络问题,如重定向、重试以及超时,为开发者提供了一个简单且强大的接口来进行网络通信。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON格式被广泛用于Web服务之间的数据交换,尤其是在RESTful API中。
当使用OkHttp与远程服务器进行交互,且服务器返回的数据格式为JSON时,开发者通常需要将这些JSON数据转换为Java对象以便于进一步处理。这一过程涉及两个关键步骤:
-
请求JSON数据:使用OkHttp发送HTTP请求(如GET或POST)到指定的URL,获取服务器响应的JSON字符串。OkHttp通过构建请求、执行请求并读取响应体中的数据来完成这一过程。
-
解析JSON数据:获取到JSON字符串后,需要将其转换为Java对象。常用的做法是借助库如Gson或Jackson。这些库提供了将JSON字符串转换为Java对象(称为序列化)和将Java对象转换回JSON字符串(称为反序列化)的功能。例如,Gson通过调用
Gson.fromJson(jsonString, ClassName.class)
方法即可将JSON字符串解析为指定类的对象。
结合这两个步骤,开发者能够轻松地使用OkHttp发送网络请求获取JSON数据,并利用Gson等工具解析这些数据,实现与服务器的高效数据交换,支撑各种应用功能,如用户登录认证、数据列表加载、内容搜索等。
一、添加依赖
目标依赖:
com.squareup.okhttp3:okhttp:4.9.0
com.squareup.retrofit2:converter-gson:2.9.0
com.google.code.gson:gson:2.8.8
添加Library:
输入域名(com.squareup.okhttp3):
添加完成:
二、网络访问
目标地址:
t.weather.itboy.net/api/weather/city/101260101
允许网络访问:
<uses-permission android:name="android.permission.INTERNET"/>
android:networkSecurityConfig="@xml/network"
网络安全配置文件:
在你的Android项目的res/xml
目录下,创建一个名为network_security_config.xml
的文件(如果该目录不存在,请先创建它),并添加如下配置以允许特定域名的明文流量(t.weather.itboy.net)(这不推荐用于生产环境,仅作示例)针对http,https不用:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">t.weather.itboy.net</domain></domain-config>
</network-security-config>
三、构建实例
1.定义请求URL:
String url = "http://t.weather.itboy.net/api/weather/city/101260101";
2.创建OkHttpClient实例:
OkHttpClient client = new OkHttpClient();
3.构建Request对象:
Request request = new Request.Builder().url(url).build();
四、网络请求
1.发起异步网络请求(enqueue):
client.newCall(request).enqueue(new Callback() { ... });
2.处理响应结果:
onFailure:
如果请求失败,会调用此方法,打印错误信息到日志。
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {Log.d("22",e.getMessage());
}
onResponse:
当请求成功并收到响应时,会调用此方法,。
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {...
}
五、响应处理
目标数据:
ReSon 方法:
- try-with-resources: 使用
try (ResponseBody responseBody = response.body())
自动管理ResponseBody
的关闭,确保资源被正确释放。 - 检查响应状态:
response.isSuccessful()
确认HTTP响应状态码表示成功(通常指200-299范围内的状态码)。 - 读取响应体:
responseBody.string()
将响应体内容转换为字符串,这是读取网络响应中数据的标准方式。 - UI更新: 通过
runOnUiThread(Runnable)
确保在主线程中执行UI更新操作,避免Android的主线程操作限制。这里调用GsonJson(json)
方法进一步处理JSON数据。 - 异常处理: 使用
catch (IOException e)
捕获并记录在读取响应体时可能出现的任何I/O异常。
private void ReSon(Response response) {try (ResponseBody responseBody = response.body()) {// 检查响应是否成功(HTTP状态码为200-299)if (!response.isSuccessful() || responseBody == null) {Log.e("22", "错误" + response);return; // 响应不成功或无响应体时,记录错误并退出方法}// 将响应体转换为字符串final String json = responseBody.string();// 在UI线程更新界面runOnUiThread(new Runnable() {@Overridepublic void run() {// 调用GsonJson方法解析JSON数据GsonJson(json);}});} catch (IOException e) {// 捕获并记录读取响应体时可能发生的IO异常Log.e("22", "错误", e);}
}
GsonJson 方法:
-
创建Gson对象:
Gson gson = new Gson();
这一行创建了Gson的实例,Gson是一个流行的Java库,用于将Java对象转换为JSON字符串,或者反过来将JSON字符串转换为等效的Java对象。 -
解析JSON:
MyJson myJson = gson.fromJson(json, MyJson.class);
这行代码是Gson的核心用法之一,它接收一个JSON格式的字符串和一个Java类的Class对象作为参数。Gson会尝试将JSON字符串转换为指定类的实例。在这个例子中,它会将json
字符串转换为MyJson
类的一个对象。 -
更新UI:
textView.setText(myJson.getDate());
这行代码假设在一个Android环境下,通过setText
方法将从JSON中解析出的日期设置到一个名为textView
的TextView组件上显示。这里调用了MyJson
类的getDate
方法来获取日期字符串。
private void GsonJson(String json){// 实例化Gson对象,Gson是Google开发的用来简化JSON解析和生成的库Gson gson = new Gson();try {// 使用Gson的fromJson方法,将JSON字符串转换为MyJson对象// 这要求MyJson类的结构必须与JSON数据结构相对应// MyJson类包含date字段以及一个嵌套的CityInfo对象MyJson myJson = gson.fromJson(json, MyJson.class);// 更新UI组件,将解析出的日期数据显示在textView中// 确保此操作在主线程中执行,避免UI更新的线程安全问题textView.setText(myJson.getDate());// 获取MyJson对象中的CityInfo对象,并从中读取city字段的值// 将城市名称显示在textView2中textView2.setText(myJson.getCityInfo().getCity());} catch (Exception e) {// 捕获并处理可能发生的异常,例如JSON数据格式不匹配或UI更新问题// 实际应用中可能需要更具体的异常处理逻辑Log.e("JsonParsingError", "解析JSON数据时发生错误: " + e.getMessage());}
}
MyJson
类
-
定义数据结构:
MyJson
类定义了一个简单的数据模型,用来匹配JSON数据中的结构。在这个例子中,只定义了一个字段date
,用于存储日期字符串。 -
getter方法:
getDate()
是一个标准的getter方法,用于获取date
字段的值。在GsonJson
方法中,通过这个getter方法访问解析后的日期信息。
public class MyJson {// 定义一个私有字段,用于存储日期信息private String date;// 定义一个内部类,表示城市信息private CityInfo cityInfo;// 获取日期的方法public String getDate() {return date;}// 获取城市信息的方法public CityInfo getCityInfo() {return cityInfo;}// 内部类 CityInfo,用来封装城市信息private class CityInfo {// 城市名称的私有字段private String city;// 获取城市名称的方法public String getCity() {return city;}}
}