我刚开始接触 okhttp3 的时候,就想要发个请求而已,网络文章大多介绍原理、细节,对于入门者,还不能或者不想接触这些,只想发送网络请求感受一番。下面步骤是满足 restful 风格的 get/post/delete/put 请求的异步请求封装,开箱即用。

1. 添加网络访问权限

修改 AndroidManifest.xml 文件,添加网络访问权限。

  1. <uses-permission android:name="android.permission.INTERNET"/>

2. 添加 okhttp 依赖

修改 build.gradle 文件,添加 okhttp 的依赖。

  1. implementation 'com.squareup.okhttp3:okhttp:3.12.0'

3. 新建 HttpUtil.java 类

restful 风格的 get/post/delete/put 请求封装。还不完善,不过对于 Py-novel 项目来说是够用了。请求 http 请求一直失败,请求 https 就能成功返回,不知道是不是内部限制。

如果有变量报红线,请注意看该类所属的包是否为 okhttp3,下面文件最上方列出了我用到的类所属的包。

  1. package top.dkvirus.novel.okhttptest;
  2. import android.util.Log;
  3. import org.json.JSONException;
  4. import org.json.JSONObject;
  5. import java.util.Map;
  6. import okhttp3.Call;
  7. import okhttp3.Callback;
  8. import okhttp3.MediaType;
  9. import okhttp3.OkHttpClient;
  10. import okhttp3.Request;
  11. import okhttp3.RequestBody;
  12. public class HttpUtil {
  13. private static final String TAG = "HttpUtil";
  14. /**
  15. * get 请求
  16. */
  17. public static void get (String url, Callback callback) {
  18. OkHttpClient client = new OkHttpClient();
  19. Request request = new Request.Builder()
  20. .url(url)
  21. .build();
  22. client.newCall(request).enqueue(callback);
  23. }
  24. /**
  25. * post 请求
  26. */
  27. public static void post (String url, Map<String, Object> map, Callback callback) {
  28. OkHttpClient client = new OkHttpClient();
  29. MediaType JSON = MediaType.parse("application/json; charset=utf-8");
  30. JSONObject jsonObject = new JSONObject();
  31. try {
  32. for (String key : map.keySet()) {
  33. jsonObject.put(key, map.get(key));
  34. }
  35. } catch (JSONException e) {
  36. Log.d(TAG, "POST 请求 json 格式参数解析错误");
  37. e.printStackTrace();
  38. }
  39. Log.d(TAG, "POST 请求参数:" + jsonObject.toString());
  40. RequestBody body = RequestBody.create(JSON, jsonObject.toString());
  41. Request request = new Request.Builder()
  42. .url(url)
  43. .post(body)
  44. .build();
  45. client.newCall(request).enqueue(callback);
  46. }
  47. /**
  48. * delete 请求
  49. */
  50. public static void delete (String url, Callback callback) {
  51. OkHttpClient client = new OkHttpClient();
  52. Request request = new Request.Builder()
  53. .url(url)
  54. .delete()
  55. .build();
  56. client.newCall(request).enqueue(callback);
  57. }
  58. /**
  59. * put 请求
  60. */
  61. public static void put (String url, Map<String, Object> map, Callback callback) {
  62. OkHttpClient client = new OkHttpClient();
  63. MediaType JSON = MediaType.parse("application/json; charset=utf-8");
  64. JSONObject jsonObject = new JSONObject();
  65. try {
  66. for (String key : map.keySet()) {
  67. jsonObject.put(key, map.get(key));
  68. }
  69. } catch (JSONException e) {
  70. Log.d(TAG, "PUT 请求 json 格式参数解析错误");
  71. e.printStackTrace();
  72. }
  73. RequestBody body = RequestBody.create(JSON, jsonObject.toString());
  74. Request request = new Request.Builder()
  75. .url(url)
  76. .put(body)
  77. .build();
  78. client.newCall(request).enqueue(callback);
  79. }
  80. }

4. 使用示例

  1. package top.dkvirus.novel.okhttptest;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.widget.TextView;
  6. import java.io.IOException;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import okhttp3.Call;
  10. import okhttp3.Callback;
  11. import okhttp3.Response;
  12. public class MainActivity extends AppCompatActivity {
  13. private static final String TAG = "MainActivity";
  14. TextView resp_text;
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. resp_text = findViewById(R.id.resp_text);
  20. // Get 请求示例代码
  21. // HttpUtil.get("https://novel.dkvirus.top/api/test/gysw/novel/classify", new Callback() {
  22. // @Override
  23. // public void onFailure(Call call, IOException e) {
  24. // Log.d(TAG, "onFailure: 失败了");
  25. // }
  26. //
  27. // @Override
  28. // public void onResponse(Call call, Response response) throws IOException {
  29. // Log.d(TAG, "onResponse: 成功了");
  30. // Log.d(TAG, "onResponse: " + response.body().string());
  31. // }
  32. // });
  33. // Post 请求示例代码
  34. // Map<String, Object> map = new HashMap<String, Object>();
  35. // map.put("username", "18056891356");
  36. // map.put("password", "123456");
  37. // map.put("client_type", "MOBILE");
  38. // HttpUtil.post("https://novel.dkvirus.top/api/test/gysw/user/info", map, new Callback() {
  39. // @Override
  40. // public void onFailure(Call call, IOException e) {
  41. // Log.d(TAG, "onFailure: 新增数据失败");
  42. // }
  43. //
  44. // @Override
  45. // public void onResponse(Call call, Response response) throws IOException {
  46. // Log.d(TAG, "onResponse: 新增数据成功");
  47. // Log.d(TAG, "onResponse: " + response);
  48. // }
  49. // });
  50. // Delete 请求示例代码
  51. // HttpUtil.delete("https://novel.dkvirus.top/api/test/gysw/shelf/29", new Callback() {
  52. // @Override
  53. // public void onFailure(Call call, IOException e) {
  54. // Log.d(TAG, "onFailure: 删除数据失败");
  55. // }
  56. //
  57. // @Override
  58. // public void onResponse(Call call, Response response) throws IOException {
  59. // Log.d(TAG, "onResponse: 删除数据成功");
  60. // Log.d(TAG, "onResponse: " + response);
  61. // }
  62. // });
  63. // Post 请求示例代码
  64. Map<String, Object> map = new HashMap<>();
  65. map.put("recent_chapter_url", "https://www.biquge5200.cc/0_7/2046.html");
  66. HttpUtil.put("https://novel.dkvirus.top/api/test/gysw/shelf/30", map, new Callback() {
  67. @Override
  68. public void onFailure(Call call, IOException e) {
  69. Log.d(TAG, "onFailure: 修改数据失败");
  70. }
  71. @Override
  72. public void onResponse(Call call, Response response) throws IOException {
  73. Log.d(TAG, "onResponse: 修改数据成功");
  74. Log.d(TAG, "onResponse: " + response);
  75. }
  76. });
  77. }
  78. }

5. 解析数据

okhttp3 默认返回数据为字符串类型,想要转换为 json 格式的数据需要怎么做?

这里使用 gson 方式解析响应,第一步在 build.gradle 中加入 gson 依赖。

  1. implementation 'com.google.code.gson:gson:2.7'

在上面的 HttpUtil.java 中添加一个方法。

  1. public static <T> T parseJSONWithGSON (String jsonData, TypeToken<T> typeToken) {
  2. Gson gson = new Gson();
  3. T t = gson.fromJson(jsonData, typeToken.getType());
  4. return t;
  5. }

响应的数据结构如下:

  1. {
  2. code: "0000",
  3. message: "操作成功",
  4. data: {
  5. userId: 1,
  6. username: "dkvirus",
  7. }
  8. }

定义实体类,实体类结构要与返回的数据结构一一对应。

  1. public class DetailResult {
  2. private String code;
  3. private String message;
  4. private Detail data;
  5. // get/set 方法自己补充
  6. }
  7. // 另外一个 Java 类
  8. public class Detail {
  9. private int userId;
  10. private String username;
  11. // get/set 方法自己补充
  12. }

解析

  1. String responseData = response.body().string();
  2. DetailResult detailResult = HttpUtil.parseJSONWithGSON(responseData, new TypeToken<DetailResult>(){});