我刚开始接触 okhttp3 的时候,就想要发个请求而已,网络文章大多介绍原理、细节,对于入门者,还不能或者不想接触这些,只想发送网络请求感受一番。下面步骤是满足 restful 风格的 get/post/delete/put 请求的异步请求封装,开箱即用。
1. 添加网络访问权限
修改 AndroidManifest.xml 文件,添加网络访问权限。
<uses-permission android:name="android.permission.INTERNET"/>
2. 添加 okhttp 依赖
修改 build.gradle 文件,添加 okhttp 的依赖。
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
3. 新建 HttpUtil.java 类
restful 风格的 get/post/delete/put 请求封装。还不完善,不过对于 Py-novel 项目来说是够用了。请求 http 请求一直失败,请求 https 就能成功返回,不知道是不是内部限制。
如果有变量报红线,请注意看该类所属的包是否为 okhttp3,下面文件最上方列出了我用到的类所属的包。
package top.dkvirus.novel.okhttptest;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class HttpUtil {
private static final String TAG = "HttpUtil";
/**
* get 请求
*/
public static void get (String url, Callback callback) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(callback);
}
/**
* post 请求
*/
public static void post (String url, Map<String, Object> map, Callback callback) {
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
JSONObject jsonObject = new JSONObject();
try {
for (String key : map.keySet()) {
jsonObject.put(key, map.get(key));
}
} catch (JSONException e) {
Log.d(TAG, "POST 请求 json 格式参数解析错误");
e.printStackTrace();
}
Log.d(TAG, "POST 请求参数:" + jsonObject.toString());
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(request).enqueue(callback);
}
/**
* delete 请求
*/
public static void delete (String url, Callback callback) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.delete()
.build();
client.newCall(request).enqueue(callback);
}
/**
* put 请求
*/
public static void put (String url, Map<String, Object> map, Callback callback) {
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
JSONObject jsonObject = new JSONObject();
try {
for (String key : map.keySet()) {
jsonObject.put(key, map.get(key));
}
} catch (JSONException e) {
Log.d(TAG, "PUT 请求 json 格式参数解析错误");
e.printStackTrace();
}
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url(url)
.put(body)
.build();
client.newCall(request).enqueue(callback);
}
}
4. 使用示例
package top.dkvirus.novel.okhttptest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
TextView resp_text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resp_text = findViewById(R.id.resp_text);
// Get 请求示例代码
// HttpUtil.get("https://novel.dkvirus.top/api/test/gysw/novel/classify", new Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
// Log.d(TAG, "onFailure: 失败了");
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// Log.d(TAG, "onResponse: 成功了");
// Log.d(TAG, "onResponse: " + response.body().string());
// }
// });
// Post 请求示例代码
// Map<String, Object> map = new HashMap<String, Object>();
// map.put("username", "18056891356");
// map.put("password", "123456");
// map.put("client_type", "MOBILE");
// HttpUtil.post("https://novel.dkvirus.top/api/test/gysw/user/info", map, new Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
// Log.d(TAG, "onFailure: 新增数据失败");
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// Log.d(TAG, "onResponse: 新增数据成功");
// Log.d(TAG, "onResponse: " + response);
// }
// });
// Delete 请求示例代码
// HttpUtil.delete("https://novel.dkvirus.top/api/test/gysw/shelf/29", new Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
// Log.d(TAG, "onFailure: 删除数据失败");
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// Log.d(TAG, "onResponse: 删除数据成功");
// Log.d(TAG, "onResponse: " + response);
// }
// });
// Post 请求示例代码
Map<String, Object> map = new HashMap<>();
map.put("recent_chapter_url", "https://www.biquge5200.cc/0_7/2046.html");
HttpUtil.put("https://novel.dkvirus.top/api/test/gysw/shelf/30", map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: 修改数据失败");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: 修改数据成功");
Log.d(TAG, "onResponse: " + response);
}
});
}
}
5. 解析数据
okhttp3 默认返回数据为字符串类型,想要转换为 json 格式的数据需要怎么做?
这里使用 gson 方式解析响应,第一步在 build.gradle 中加入 gson 依赖。
implementation 'com.google.code.gson:gson:2.7'
在上面的 HttpUtil.java 中添加一个方法。
public static <T> T parseJSONWithGSON (String jsonData, TypeToken<T> typeToken) {
Gson gson = new Gson();
T t = gson.fromJson(jsonData, typeToken.getType());
return t;
}
响应的数据结构如下:
{
code: "0000",
message: "操作成功",
data: {
userId: 1,
username: "dkvirus",
}
}
定义实体类,实体类结构要与返回的数据结构一一对应。
public class DetailResult {
private String code;
private String message;
private Detail data;
// get/set 方法自己补充
}
// 另外一个 Java 类
public class Detail {
private int userId;
private String username;
// get/set 方法自己补充
}
解析
String responseData = response.body().string();
DetailResult detailResult = HttpUtil.parseJSONWithGSON(responseData, new TypeToken<DetailResult>(){});