官网

https://square.github.io/okhttp/recipes/

快速入门

添加 jar 到 pom.xml

  1. <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
  2. <dependency>
  3. <groupId>com.squareup.okhttp3</groupId>
  4. <artifactId>okhttp</artifactId>
  5. <version>4.9.3</version>
  6. </dependency>

测试代码

  1. package basic_okhttp;
  2. import lombok.SneakyThrows;
  3. import okhttp3.*;
  4. import okhttp3.Request.Builder;
  5. import org.junit.jupiter.api.Test;
  6. import java.io.File;
  7. import java.io.IOException;
  8. /**
  9. * The type Okhttp study.
  10. */
  11. public class OkhttpStudy {
  12. private final OkHttpClient client = new OkHttpClient();
  13. private final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
  14. /**
  15. * Test get.
  16. */
  17. @SneakyThrows
  18. @Test
  19. void testGet() {
  20. Request request = new Builder()
  21. .url("https://publicobject.com/helloworld.txt")
  22. .build();
  23. try (Response response = client.newCall(request).execute()) {
  24. if (!response.isSuccessful()) {
  25. throw new IOException("Unexpected code " + response);
  26. }
  27. Headers responseHeaders = response.headers();
  28. for (int i = 0; i < responseHeaders.size(); i++) {
  29. System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
  30. }
  31. System.out.println(response.body().string());
  32. }
  33. }
  34. /**
  35. * 测试添加请求头
  36. */
  37. @SneakyThrows
  38. @Test
  39. void testHeaders() {
  40. Request request = new Request.Builder()
  41. .url("https://api.github.com/repos/square/okhttp/issues")
  42. .header("User-Agent", "OkHttp Headers.java")
  43. .addHeader("Accept", "application/json; q=0.5")
  44. .addHeader("Accept", "application/vnd.github.v3+json")
  45. .build();
  46. try (Response response = client.newCall(request).execute()) {
  47. if (!response.isSuccessful()) {
  48. throw new IOException("Unexpected code " + response);
  49. }
  50. System.out.println("Server: " + response.header("Server"));
  51. System.out.println("Date: " + response.header("Date"));
  52. System.out.println("Vary: " + response.headers("Vary"));
  53. }
  54. }
  55. /**
  56. * 测试 Post 请求
  57. */
  58. @SneakyThrows
  59. @Test
  60. void testPost() {
  61. String postBody = """
  62. Releases
  63. --------
  64. *_ 1.0_ May 6, 2013
  65. * _1.1_ June 15, 2013
  66. * 1.2_ August 11, 2013
  67. """;
  68. Request request = new Request.Builder()
  69. .url("https://api.github.com/markdown/raw")
  70. .post(RequestBody.create(postBody, MEDIA_TYPE_MARKDOWN))
  71. .build();
  72. try (Response response = client.newCall(request).execute()) {
  73. if (!response.isSuccessful()) {
  74. throw new IOException("Unexpected code " + response);
  75. }
  76. System.out.println(response.body().string());
  77. }
  78. }
  79. /**
  80. * 测试提交文件请求
  81. */
  82. @SneakyThrows
  83. @Test
  84. void testFile() {
  85. File file = new File("README.md");
  86. Request request = new Request.Builder()
  87. .url("https://api.github.com/markdown/raw")
  88. .post(RequestBody.create(file, MEDIA_TYPE_MARKDOWN))
  89. .build();
  90. try (Response response = client.newCall(request).execute()) {
  91. if (!response.isSuccessful()) {
  92. throw new IOException("Unexpected code " + response);
  93. }
  94. System.out.println(response.body().string());
  95. }
  96. }
  97. /**
  98. * 测试 form 表单
  99. */
  100. @SneakyThrows
  101. @Test
  102. void testForm() {
  103. RequestBody formBody = new FormBody.Builder()
  104. .add("search", "Jurassic Park")
  105. .build();
  106. Request request = new Request.Builder()
  107. .url("https://en.wikipedia.org/w/index.php")
  108. .post(formBody)
  109. .build();
  110. try (Response response = client.newCall(request).execute()) {
  111. if (!response.isSuccessful()) {
  112. throw new IOException("Unexpected code " + response);
  113. }
  114. System.out.println(response.body().string());
  115. }
  116. }
  117. }

工具类封装

枚举类

主要封装不同的 Content-type,方便管理

package com.polo.testplatform.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;
import okhttp3.MediaType;

/**
 * The enum Okhttp mediatype.
 */
@Getter
@AllArgsConstructor
public enum OkHttpMediaType {

    /**
     * 声明 Content-type
     * application 开头-常用
     */
    MEDIA_TYPE_JSON(MediaType.parse("application/json; charset=utf-8")),
    MEDIA_TYPE_XML(MediaType.parse("application/xml; charset=utf-8")),
    MEDIA_TYPE_FORM_URLENCODED(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8")),

    /**
     * 声明 Content-type
     * text 开头-常用
     */
    MEDIA_TYPE_MARKDOWN(MediaType.parse("text/x-markdown; charset=utf-8")),
    MEDIA_TYPE_HTML(MediaType.parse("text/html; charset=utf-8")),
    MEDIA_TYPE_PLAINTEXT(MediaType.parse("text/plain; charset=utf-8")),

    /**
     * 声明 Content-type
     * multipart 开头
     * 需要在表单中进行文件上传时,就需要使用该格式
     */
    MEDIA_TYPE_MULTIPART(MediaType.parse("multipart/form-data; charset=utf-8"));


    private final MediaType type;
}

工具类

package com.polo.testplatform.utils;

import com.alibaba.fastjson.JSON;
import com.polo.testplatform.enums.OkHttpMediaType;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 关于 OkHttp 的工具类
 */
@Slf4j
@Component
public class OkHttpUtils {

    private final OkHttpClient client = new OkHttpClient();
    private Map<String, String> headersMap;
    private Map<String, String> paramsMap;
    private String url;
    private Request.Builder request;


    /**
     * 设置 url
     *
     * @param url the url
     * @return 工具类本身
     */
    public OkHttpUtils url(String url) {
        this.url = url;
        return this;
    }

    /**
     * 添加请求参数
     *
     * @param name  请求参数 key
     * @param value 请求参数 value
     * @return 工具类本身
     */
    public OkHttpUtils addParams(String name, String value) {
        if (MapUtils.isEmpty(paramsMap)) {
            paramsMap = new HashMap<>(16);
        }
        paramsMap.put(name, value);
        return this;
    }

    /**
     * 重载,添加请求参数
     *
     * @param map 请求参数组成的 map
     * @return 工具类本身
     */
    public OkHttpUtils addParams(Map<String, String> map) {
        if (MapUtils.isEmpty(paramsMap)) {
            paramsMap = new HashMap<>(16);
        }
        paramsMap.putAll(map);
        return this;
    }


    /**
     * 添加请求头
     *
     * @param name  请求头 key
     * @param value 请求头 value
     * @return 工具类本身
     */
    public OkHttpUtils addHeader(String name, String value) {
        if (MapUtils.isEmpty(headersMap)) {
            headersMap = new HashMap<>(16);
        }
        headersMap.put(name, value);
        return this;
    }

    /**
     * 重载,添加请求头
     *
     * @param map 请求头组成的 map
     * @return 工具类本身
     */
    public OkHttpUtils addHeader(Map<String, String> map) {
        if (MapUtils.isEmpty(headersMap)) {
            headersMap = new HashMap<>(16);
        }
        headersMap.putAll(map);
        return this;
    }

    /**
     * 处理 get 请求
     *
     * @return 工具类本身
     */
    public OkHttpUtils get() {
        request = new Request.Builder().get();
        StringBuilder urlBuilder = new StringBuilder(url);
        if (MapUtils.isNotEmpty(paramsMap)) {
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                urlBuilder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
                        .append("=")
                        .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
                        .append("&");
            }
            urlBuilder.deleteCharAt(urlBuilder.length() - 1);
        }
        request.url(urlBuilder.toString());
        return this;
    }

    /**
     * 最终处理 post 请求
     *
     * @param requestBody the request body
     * @return 工具类本身
     */
    public OkHttpUtils post(RequestBody requestBody) {
        request = new Request.Builder()
                .post(requestBody)
                .url(url);
        return this;
    }

    /**
     * 处理 post 请求
     *
     * @param data      the data
     * @param mediaType Content-type
     * @return 工具类本身
     */
    public OkHttpUtils post(String data, MediaType mediaType) {
        return post(RequestBody.create(data, mediaType));
    }

    /**
     * 处理上传文件的 post 请求
     *
     * @param file      the file
     * @param mediaType Content-type
     * @return 工具类本身
     */
    public OkHttpUtils post(File file, MediaType mediaType) {
        return post(RequestBody.create(file, mediaType));
    }

    /**
     * json post 请求
     *
     * @return 工具类本身
     */
    public OkHttpUtils postJson() {
        String json = JSON.toJSONString(paramsMap);
        return post(json, OkHttpMediaType.MEDIA_TYPE_JSON.getType());
    }


    /**
     * json post 请求
     *
     * @param map the map
     * @return 工具类本身
     */
    public OkHttpUtils postJson(Map<String, String> map) {
        String json = JSON.toJSONString(map);
        return post(json, OkHttpMediaType.MEDIA_TYPE_JSON.getType());
    }

    /**
     * form 表单 post 请求
     *
     * @return 工具类本身
     */
    public OkHttpUtils postForm() {
        FormBody.Builder formBody = new FormBody.Builder();
        paramsMap.forEach(formBody::add);
        return post(formBody.build());
    }

    /**
     * form 表单 post 请求
     *
     * @param map the map
     * @return 工具类本身
     */
    public OkHttpUtils postForm(Map<String, String> map) {
        FormBody.Builder formBody = new FormBody.Builder();
        map.forEach(formBody::add);
        return post(formBody.build());
    }

    /**
     * 同步请求
     *
     * @return the string
     */
    @SneakyThrows
    public String sync() {
        if (MapUtils.isNotEmpty(headersMap)) {
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                request.addHeader(entry.getKey(), entry.getValue());
            }
        }
        String result = null;
        try (Response response = client.newCall(request.build()).execute()) {
            if (!response.isSuccessful()) {
                log.error("Unexpected code " + response);
            }
            result = response.body().string();
            log.info("response body " + result);
        }
        return result;
    }
}

重写测试类

package com.polo.testplatform.utils;

import com.polo.testplatform.enums.OkHttpMediaType;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@SpringBootTest
class TestOkHttpUtils {

    @Autowired
    private OkHttpUtils okHttpUtils;

    @Test
    void testGet() {
        String response = okHttpUtils.url("https://publicobject.com/helloworld.txt").get().sync();
        log.info(response);
    }

    //
    @SneakyThrows
    @Test
    void testHeaders() {
        Map<String, String> headers = new HashMap<>();
        headers.put("Accept", "application/vnd.github.v3+json");
        String response = okHttpUtils.url("https://api.github.com/repos/square/okhttp/issues")
                .addHeader("Accept", "application/json; q=0.5")
                .addHeader(headers)
                .get()
                .sync();
        log.info(response);
    }

    @SneakyThrows
    @Test
    void testPost() {
        String postBody = """
                Releases
                --------
                 *_ 1.0_ May 6, 2013
                 * _1.1_ June 15, 2013
                 *  1.2_ August 11, 2013
                """;
        String response = okHttpUtils.url("https://api.github.com/markdown/raw")
                .post(postBody, OkHttpMediaType.MEDIA_TYPE_MARKDOWN.getType())
                .sync();
        log.info(response);
    }


    @SneakyThrows
    @Test
    void testFile() {
        File file = new File("README.md");
        String response = okHttpUtils.url("https://api.github.com/markdown/raw")
                .post(file, OkHttpMediaType.MEDIA_TYPE_MARKDOWN.getType())
                .sync();
        log.info(response);
    }

    //
    @SneakyThrows
    @Test
    void testForm() {
        String response = okHttpUtils.url("https://en.wikipedia.org/w/index.php")
                .addParams("search", "Jurassic Park")
                .postForm()
                .sync();
        log.info(response);
    }
}

可以看到代码量省了不少