说明
HTTP 基本知识
序号 | 方法 | 请求体 | 描述 |
---|---|---|---|
1 | GET | 一般没有,可以有 | 从服务器获取资源。用于请求数据而不对数据进行更改。例如,从服务器获取网页、图片等。 |
2 | POST | 有 | 向服务器发送数据以创建新资源。常用于提交表单数据或上传文件。发送的数据包含在请求体中。 |
3 | PUT | 有 | 向服务器发送数据以更新现有资源。如果资源不存在,则创建新的资源。与 POST 不同,PUT 通常是幂等的,即多次执行相同的 PUT 请求不会产生不同的结果。 |
4 | DELETE | 有 | 从服务器删除指定的资源。请求中包含要删除的资源标识符。 |
5 | PATCH | 有 | 对资源进行部分修改。与 PUT 类似,但 PATCH 只更改部分数据而不是替换整个资源。 |
6 | HEAD | 无 | 类似于 GET,但服务器只返回响应的头部,不返回实际数据。用于检查资源的元数据(例如,检查资源是否存在,查看响应的头部信息)。 |
7 | OPTIONS | 无 | 返回服务器支持的 HTTP 方法。用于检查服务器支持哪些请求方法,通常用于跨域资源共享(CORS)的预检请求。 |
8 | TRACE | 无 | 回显服务器收到的请求,主要用于诊断。客户端可以查看请求在服务器中的处理路径。 |
9 | CONNECT | - | 建立一个到服务器的隧道,通常用于 HTTPS 连接。客户端可以通过该隧道发送加密的数据。 |
POST、PUT、DELETE、PATCH 一般是有请求体的,GET、HEAD、OPTIONS、TRACE 一般没有请求体(GET 请求其实也可以包含请求体,Spring Boot 也可以接收 GET 请求的请求体),CONNECT 方法并不是直接由用户调用的,而是在建立连接时使用的。
功能
-
支持发送 GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE 请求,且均有同步、异步调用方式;
-
支持的请求体目前支持常见的 JSON 格式请求体
application/json
和表单请求体multipart/mixed
,表单请求体支持传输 File、InputStream、byte[]类型的(文件)对象; -
POST、PUT、DELETE、PATCH 支持以上两种请求体;OkHttp 中,GET 不支持请求体,所以工具类也不支持 GET 请求携带请求体。
代码
引入依赖
xml
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-jvm</artifactId>
<version>5.0.0</version>
</dependency>
注:okhttp 5.x版本,需要引用okhttp-jvm,如果IDEA版本不够新(如2024.1.2),引入okhttp 5.x版本后,idea代码联想可能无法关联上okhttp相关类(实测社区版2025.1.1.1可以)。如果遇到此种情况,可以引入4.x版本,如下:
xml
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
HTTP请求类型枚举类
java
package com.example.study.enums;
import lombok.Getter;
@Getter
public enum HttpMethodEnum {
GET("GET"),
POST("POST"),
PUT("PUT"),
PATCH("PATCH"),
DELETE("DELETE"),
OPTIONS("OPTIONS"),
HEAD("HEAD"),
TRACE("TRACE"),
CONNECT("CONNECT");
private String value;
HttpMethodEnum(String value) {
this.value = value;
}
}
HTTP响应类
java
package com.example.study.util;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.Map;
@Setter
@Getter
@ToString
@Builder
@AllArgsConstructor
public class HttpUtilResponse {
private boolean isSuccessful;
private boolean isRedirect;
private int code;
private Map<String, String> headers;
private byte[] body;
public String getStringBody() {
return body == null ? "null" : new String(body);
}
}
HTTP请求工具类(同步)
java
package com.example.study.util;
import com.alibaba.fastjson.JSON;
import com.example.study.enums.HttpMethodEnum;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* HTTP请求工具类(同步)
*/
@Slf4j
public class HttpUtils {
private static final MediaType APPLICATION_JSON_UTF8 = MediaType.parse("application/json; charset=utf-8");
private static final MediaType APPLICATION_OCTET_STREAM = MediaType.parse("application/octet-stream");
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.build();
/**
* 执行get请求
*
* @param url url
* @return 请求结果
*/
public static HttpUtilResponse get(String url) {
return get(url, null);
}
/**
* 执行get请求
*
* @param url url
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse get(String url, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.get().build();
return execute(request);
}
/**
* 执行post请求(请求体为json)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse post(String url, Map<String, ?> body) {
return post(url, body, null);
}
/**
* 执行post请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse post(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.POST);
Request request = builder.build();
return execute(request);
}
/**
* 执行post请求(请求体为form)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse postForm(String url, Map<String, ?> body) {
return postForm(url, body, null);
}
/**
* 执行post请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse postForm(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.POST);
Request request = builder.build();
return execute(request);
}
/**
* 执行put请求(请求体为json)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse put(String url, Map<String, ?> body) {
return put(url, body, null);
}
/**
* 执行put请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse put(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.PUT);
Request request = builder.build();
return execute(request);
}
/**
* 执行put请求(请求体为form)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse putForm(String url, Map<String, ?> body) {
return putForm(url, body, null);
}
/**
* 执行put请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse putForm(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.PUT);
Request request = builder.build();
return execute(request);
}
/**
* 执行patch请求(请求体为json)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse patch(String url, Map<String, ?> body) {
return patch(url, body, null);
}
/**
* 执行patch请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse patch(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.PATCH);
Request request = builder.build();
return execute(request);
}
/**
* 执行patch请求(请求体为form)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse patchForm(String url, Map<String, ?> body) {
return patchForm(url, body, null);
}
/**
* 执行patch请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse patchForm(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.PATCH);
Request request = builder.build();
return execute(request);
}
/**
* 执行delete请求(请求体为json)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse delete(String url, Map<String, ?> body) {
return delete(url, body, null);
}
/**
* 执行delete请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse delete(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.DELETE);
Request request = builder.build();
return execute(request);
}
/**
* 执行delete请求(请求体为form)
*
* @param url url
* @param body 请求体
* @return 请求结果
*/
public static HttpUtilResponse deleteForm(String url, Map<String, ?> body) {
return deleteForm(url, body, null);
}
/**
* 执行delete请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse deleteForm(String url, Map<String, ?> body, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.DELETE);
Request request = builder.build();
return execute(request);
}
/**
* 执行options请求
*
* @param url url
* @return 请求结果
*/
public static HttpUtilResponse options(String url) {
return options(url, null);
}
/**
* 执行options请求
*
* @param url url
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse options(String url, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.method(HttpMethodEnum.OPTIONS.getValue(), null).build();
return execute(request);
}
/**
* 执行head请求
*
* @param url url
* @return 请求结果
*/
public static HttpUtilResponse head(String url) {
return head(url, null);
}
/**
* 执行head请求
*
* @param url url
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse head(String url, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.head().build();
return execute(request);
}
/**
* 执行trace请求
*
* @param url url
* @return 请求结果
*/
public static HttpUtilResponse trace(String url) {
return trace(url, null);
}
/**
* 执行trace请求
*
* @param url url
* @param headers 请求头
* @return 请求结果
*/
public static HttpUtilResponse trace(String url, Map<String, String> headers) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.method(HttpMethodEnum.TRACE.getValue(), null).build();
return execute(request);
}
private static void setHeaders(Request.Builder builder, Map<String, String> headers) {
if (headers != null) {
log.info("request headers:{}", JSON.toJSONString(headers));
builder.headers(Headers.of(headers));
}
}
private static void setJsonBody(Request.Builder builder, Map<String, ?> body, HttpMethodEnum method) {
if (body == null) {
return;
}
String jsonBody = JSON.toJSONString(body);
log.info("request body json:{}", jsonBody);
RequestBody requestBody = RequestBody.create(jsonBody, APPLICATION_JSON_UTF8);
switch (method) {
case PUT -> builder.put(requestBody);
case POST -> builder.post(requestBody);
case PATCH -> builder.patch(requestBody);
case DELETE -> builder.delete(requestBody);
}
}
private static void setFormBody(Request.Builder builder, Map<String, ?> body, HttpMethodEnum method) {
if (body == null) {
return;
}
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (Map.Entry<String, ?> entry : body.entrySet()) {
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
if (entry.getValue() instanceof File file) {
log.info("form body {} is File.", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), file.getName(), RequestBody.create(file,
APPLICATION_OCTET_STREAM));
} else if (entry.getValue() instanceof InputStream is) {
try {
log.info("form body {} is InputStream.", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), entry.getKey(), RequestBody.create(is.readAllBytes(),
APPLICATION_OCTET_STREAM));
} catch (IOException exception) {
throw new RuntimeException(exception.getMessage());
}
} else if (entry.getValue() instanceof byte[] bytes) {
log.info("form body {} is byte[].", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), entry.getKey(), RequestBody.create(bytes,
APPLICATION_OCTET_STREAM));
} else if (entry.getValue() instanceof String value) {
log.info("form body {} is String. value:{}", entry.getKey(), value);
requestBodyBuilder.addFormDataPart(entry.getKey(), value);
} else {
log.info("form body {} is {}. value:{}", entry.getKey(), entry.getValue().getClass(), entry.getValue());
requestBodyBuilder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
}
}
RequestBody requestBody = requestBodyBuilder.build();
switch (method) {
case PUT -> builder.put(requestBody);
case POST -> builder.post(requestBody);
case PATCH -> builder.patch(requestBody);
case DELETE -> builder.delete(requestBody);
}
}
private static HttpUtilResponse execute(Request request) {
log.info("{} =====start send {} request. url:{}=====", timestamp(), request.method(), request.url());
long startTime = System.currentTimeMillis();
try (Response response = CLIENT.newCall(request).execute()) {
if (response.isSuccessful()) {
log.info("{} =====send {} request success. code:{}, url:{}, spend {}ms=====",
timestamp(),
request.method(),
response.code(),
request.url(),
(System.currentTimeMillis() - startTime));
} else {
log.warn("{} =====send {} request fail. code:{}, url:{}, spend {}ms=====",
timestamp(),
request.method(),
response.code(),
request.url(),
(System.currentTimeMillis() - startTime));
}
return HttpUtilResponse.builder()
.isSuccessful(response.isSuccessful())
.isRedirect(response.isRedirect())
.code(response.code())
.headers(transHeaders(response.headers()))
.body(response.body().bytes())
.build();
} catch (IOException exception) {
log.error("{} =====send {} request error. url:{}, spend {}ms=====",
timestamp(),
request.method(),
request.url(),
(System.currentTimeMillis() - startTime));
throw new RuntimeException(String.format("send %s request error. url:%s, reason:%s",
request.method(), request.url(), exception.getMessage()));
}
}
private static Map<String, String> transHeaders(Headers headers) {
Map<String, String> headerMap = new HashMap<>();
if (headers == null) {
return headerMap;
}
Set<String> names = headers.names();
for (String name : names) {
headerMap.put(name, headers.get(name));
}
return headerMap;
}
private static String timestamp() {
return FORMATTER.format(LocalDateTime.now());
}
}
HTTP请求工具类(异步)
java
package com.example.study.util;
import com.alibaba.fastjson.JSON;
import com.example.study.enums.HttpMethodEnum;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* HTTP请求工具类(异步)
*/
@Slf4j
public class HttpAsyncUtils {
private static final MediaType APPLICATION_JSON_UTF8 = MediaType.parse("application/json; charset=utf-8");
private static final MediaType APPLICATION_OCTET_STREAM = MediaType.parse("application/octet-stream");
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.build();
/**
* 执行get请求
*
* @param url url
* @param callback 请求成功后的回调函数
*/
public static void get(String url, Callback callback) {
get(url, null, callback);
}
/**
* 执行get请求
*
* @param url url
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void get(String url, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.get().build();
execute(request, callback);
}
/**
* 执行post请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void post(String url, Map<String, ?> body, Callback callback) {
post(url, body, null, callback);
}
/**
* 执行post请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void post(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.POST);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行post请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void postForm(String url, Map<String, ?> body, Callback callback) {
postForm(url, body, null, callback);
}
/**
* 执行post请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void postForm(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.POST);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行put请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void put(String url, Map<String, ?> body, Callback callback) {
put(url, body, null, callback);
}
/**
* 执行put请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void put(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.PUT);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行put请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void putForm(String url, Map<String, ?> body, Callback callback) {
putForm(url, body, null, callback);
}
/**
* 执行put请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void putForm(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.PUT);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行patch请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void patch(String url, Map<String, ?> body, Callback callback) {
patch(url, body, null, callback);
}
/**
* 执行patch请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void patch(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.PATCH);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行patch请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void patchForm(String url, Map<String, ?> body, Callback callback) {
patchForm(url, body, null, callback);
}
/**
* 执行patch请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void patchForm(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.PATCH);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行delete请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void delete(String url, Map<String, ?> body, Callback callback) {
delete(url, body, null, callback);
}
/**
* 执行delete请求(请求体为json)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void delete(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setJsonBody(builder, body, HttpMethodEnum.DELETE);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行delete请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param callback 请求成功后的回调函数
*/
public static void deleteForm(String url, Map<String, ?> body, Callback callback) {
deleteForm(url, body, null, callback);
}
/**
* 执行delete请求(请求体为form)
*
* @param url url
* @param body 请求体
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void deleteForm(String url, Map<String, ?> body, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
setFormBody(builder, body, HttpMethodEnum.DELETE);
Request request = builder.build();
execute(request, callback);
}
/**
* 执行options请求
*
* @param url url
* @param callback 请求成功后的回调函数
*/
public static void options(String url, Callback callback) {
options(url, null, callback);
}
/**
* 执行options请求
*
* @param url url
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void options(String url, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.method(HttpMethodEnum.OPTIONS.getValue(), null).build();
execute(request, callback);
}
/**
* 执行head请求
*
* @param url url
* @param callback 请求成功后的回调函数
*/
public static void head(String url, Callback callback) {
head(url, null, callback);
}
/**
* 执行head请求
*
* @param url url
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void head(String url, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.head().build();
execute(request, callback);
}
/**
* 执行trace请求
*
* @param url url
* @param callback 请求成功后的回调函数
*/
public static void trace(String url, Callback callback) {
trace(url, null, callback);
}
/**
* 执行trace请求
*
* @param url url
* @param headers 请求头
* @param callback 请求成功后的回调函数
*/
public static void trace(String url, Map<String, String> headers, Callback callback) {
if (!StringUtils.hasText(url)) {
throw new RuntimeException("url must not be null");
}
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
Request.Builder builder = new Request.Builder().url(url);
setHeaders(builder, headers);
Request request = builder.method(HttpMethodEnum.TRACE.getValue(), null).build();
execute(request, callback);
}
private static void setHeaders(Request.Builder builder, Map<String, String> headers) {
if (headers != null) {
log.info("request headers:{}", JSON.toJSONString(headers));
builder.headers(Headers.of(headers));
}
}
private static void setJsonBody(Request.Builder builder, Map<String, ?> body, HttpMethodEnum method) {
if (body == null) {
return;
}
String jsonBody = JSON.toJSONString(body);
log.info("request body json:{}", jsonBody);
RequestBody requestBody = RequestBody.create(jsonBody, APPLICATION_JSON_UTF8);
switch (method) {
case PUT -> builder.put(requestBody);
case POST -> builder.post(requestBody);
case PATCH -> builder.patch(requestBody);
case DELETE -> builder.delete(requestBody);
}
}
private static void setFormBody(Request.Builder builder, Map<String, ?> body, HttpMethodEnum method) {
if (body == null) {
return;
}
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (Map.Entry<String, ?> entry : body.entrySet()) {
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
if (entry.getValue() instanceof File file) {
log.info("form body {} is File.", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), file.getName(), RequestBody.create(file,
APPLICATION_OCTET_STREAM));
} else if (entry.getValue() instanceof InputStream is) {
try {
log.info("form body {} is InputStream.", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), entry.getKey(), RequestBody.create(is.readAllBytes(),
APPLICATION_OCTET_STREAM));
} catch (IOException exception) {
throw new RuntimeException(exception.getMessage());
}
} else if (entry.getValue() instanceof byte[] bytes) {
log.info("form body {} is byte[].", entry.getKey());
requestBodyBuilder.addFormDataPart(entry.getKey(), entry.getKey(), RequestBody.create(bytes,
APPLICATION_OCTET_STREAM));
} else if (entry.getValue() instanceof String value) {
log.info("form body {} is String. value:{}", entry.getKey(), value);
requestBodyBuilder.addFormDataPart(entry.getKey(), value);
} else {
log.info("form body {} is {}. value:{}", entry.getKey(), entry.getValue().getClass(), entry.getValue());
requestBodyBuilder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
}
}
RequestBody requestBody = requestBodyBuilder.build();
switch (method) {
case PUT -> builder.put(requestBody);
case POST -> builder.post(requestBody);
case PATCH -> builder.patch(requestBody);
case DELETE -> builder.delete(requestBody);
}
}
private static void execute(Request request, Callback callback) {
if (callback == null) {
throw new RuntimeException("callback must not be null");
}
log.info("{} =====send {} request. url:{}=====", timestamp(), request.method(), request.url());
CLIENT.newCall(request).enqueue(callback);
}
private static String timestamp() {
return FORMATTER.format(LocalDateTime.now());
}
}