前言
最近转发了一些 PDD 的 SDK,发现他代码中同一个请求方法使用不同的入参可以返回不同的出参,如果不是写死的话,就很有借鉴意义
思路:
定义两个模板类,一个为返回(response),一个为请求(request)
请求模板类
里面有个模板方法为设置出参类型
在
入参类
中继承请求模板类
添加出参
的class在
请求方法
中利用入参类
获取出参
的class,生成出参类
代码
统一返回类:Results
/**
* 用于返回
*
* @param <T>
*/
@ApiModel("统一返回类")
public class Results<T> {
public static final String ERROR = "500";
public static final String SUCCESS = "200";
/**
* 返回码
*/
@ApiModelProperty("返回码,正确码为:200")
private String resCode;
/**
* 返回消息
*/
@ApiModelProperty("返回消息")
private String msg;
/**
* 返回实体
*/
@ApiModelProperty("返回实体")
private T obj;
public static <T> Results<T> success() {
return success(SUCCESS, "成功", null);
}
public static <T> Results<T> success(String msg) {
return success(SUCCESS, msg, null);
}
public static <T> Results<T> success(T obj) {
return success(SUCCESS, "成功", obj);
}
public static <T> Results<T> success(String msg, T obj) {
return success(SUCCESS, msg, obj);
}
public static <T> Results<T> success(String resCode, String msg, T obj) {
Results<T> result = new Results<T>();
result.setResCode(resCode);
result.setMsg(msg);
result.setObj(obj);
return result;
}
public static <T> Results<T> failed() {
return failed(ERROR, "失败", null);
}
public static <T> Results<T> failed(String msg) {
return failed(ERROR, msg, null);
}
public static <T> Results<T> failed(String msg, T obj) {
return failed(ERROR, msg, obj);
}
public static <T> Results<T> failed(String resCode, String msg) {
return failed(resCode, msg, null);
}
public static <T> Results<T> failed(Integer resCode, String msg) {
return failed(String.valueOf(resCode), msg);
}
public static <T> Results<T> failed(String resCode, String msg, T obj) {
Results<T> result = new Results<T>();
result.setResCode(resCode);
result.setMsg(msg);
result.setObj(obj);
return result;
}
public String getResCode() {
return resCode;
}
public void setResCode(String resCode) {
this.resCode = resCode;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
@Override
public String toString() {
return "Results{" +
"resCode='" + resCode + '\'' +
", msg='" + msg + '\'' +
", obj=" + obj +
'}';
}
}
两个模板类(HttpCommonRequest、HttpCommonResponse)
请求模板类:HttpCommonRequest
/**
* 入参模板类
*/
@Data
@ToString
@Slf4j
public abstract class HttpCommonRequest<T> {
/**
* 请求时间
*/
private Long timestamp;
/**
* 自定义头标签
*/
private Map<String, String> headers;
/**
* 获取出参模板方法
* 例如:
* public Class<UploadFilesVo> getResponseClass() {
* return UploadFilesVo.class;
* }
*/
public abstract Class<T> getResponseClass();
public Long getTimestamp() {
if (this.timestamp == null) {
this.timestamp = System.currentTimeMillis() / 1000L;
}
return this.timestamp;
}
/**
* 获取子类的属性与值
*
* @return Map<String, String>
*/
public final Map<String, String> getParamsMap() {
Map<String, Object> paramsFrom = getParamsFrom();
return paramsFrom.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
entry -> {
String v = "null";
Object value = entry.getValue();
if (value != null) {
if (this.isPrimaryType(value)) {
v = String.valueOf(value);
} else {
v = JSON.toJSONString(value);
}
}
return v;
}
));
}
/**
* 获取子类的属性与值,主要用于 form 表单提交
*
* @return Map<String, Object>
*/
public final Map<String, Object> getParamsFrom() {
try {
Map<String, Object> paramsMap = new TreeMap<>();
paramsMap.put("timestamp", this.getTimestamp().toString());
this.setUserParams(paramsMap);
return paramsMap;
} catch (IllegalAccessException e) {
log.error("HttpCommonRequest getParamsFrom 获取表单数据失败", e);
throw new RuntimeException(e.getMessage());
}
}
/**
* 设置子类属性模板类
* 例如:
* protected void setUserParams(Map<String, Object> params) throws IllegalAccessException {
* setUserParam(params, this);
* }
*/
protected abstract void setUserParams(Map<String, Object> params) throws IllegalAccessException;
/**
* 子类可以调用该方法设置属性值
*
* @param paramMap 总参数
* @param r 子类(this)
*/
protected final <R> void setUserParam(Map<String, Object> paramMap, R r) throws IllegalAccessException {
Class<?> tClass = r.getClass();
Field[] declaredFields = tClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
Object o = declaredField.get(r);
if (o != null) {
String fieldName = declaredField.getName();
paramMap.put(fieldName, o);
}
}
}
/**
* 判断是否为基础类型
*/
private boolean isPrimaryType(Object param) {
if (param instanceof Boolean) {
return true;
} else if (param instanceof Byte) {
return true;
} else if (param instanceof Character) {
return true;
} else if (param instanceof Short) {
return true;
} else if (param instanceof Integer) {
return true;
} else if (param instanceof Long) {
return true;
} else if (param instanceof Float) {
return true;
} else if (param instanceof Double) {
return true;
} else {
return param instanceof String;
}
}
}
返回模板类:HttpCommonResponse
/**
* 出参模板类
*/
@ToString
@Data
public class HttpCommonResponse {
/**
* 返回时间
*/
private Long timestamp;
public Long getTimestamp() {
if (this.timestamp == null) {
this.timestamp = System.currentTimeMillis() / 1000L;
}
return this.timestamp;
}
}
请求方法:HttpUtils(用到了Hutool、FastJson、Lombok)
package com.example.test.utils;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.test.exception.HttpCommonException;
import com.example.test.pojo.common.HttpCommonRequest;
import com.example.test.pojo.common.HttpCommonResponse;
import com.example.test.pojo.dto.GetUserDto;
import com.example.test.pojo.dto.UploadFilesDto;
import com.example.test.pojo.vo.GetUserVO;
import com.example.test.pojo.vo.UploadFilesVo;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.util.Map;
@Slf4j
public class HttpUtils {
/**
* 默认超时时间
*/
private static final int DEFAULT_TIMEOUT = 5000;
/**
* 最小超时时间
*/
private static final int MIN_TIMEOUT = 2000;
/**
* 空参
*/
private static final String EMPTY_BODY_LOG = "{}";
/**
* 参数返回
*/
private static final TypeReference<Results<JSONObject>> RESULT_TYPE_REF = new TypeReference<Results<JSONObject>>() {
};
// ==================================== region POST方法 ====================================
public static <T extends HttpCommonResponse> T post(String url, HttpCommonRequest<T> request) {
return post(url, request, DEFAULT_TIMEOUT);
}
/**
* 普通请求
*
* @param url 链接
* @param request 入参
* @param timeout 超时时间
*/
public static <T extends HttpCommonResponse> T post(String url, HttpCommonRequest<T> request, int timeout) {
return executeJsonRequest(url, request, HttpMethod.POST, timeout);
}
public static <T extends HttpCommonResponse> T post(String url, Class<T> responseType) {
return post(url, responseType, DEFAULT_TIMEOUT);
}
/**
* 无入参有出参
*
* @param url 链接
* @param responseType 出参 class 类
* @param timeout 超时时间
*/
public static <T extends HttpCommonResponse> T post(String url, Class<T> responseType, int timeout) {
return executeEmptyRequest(url, responseType, HttpMethod.POST, timeout);
}
public static <T extends HttpCommonResponse> T postForm(String url, HttpCommonRequest<T> request) {
return postForm(url, request, DEFAULT_TIMEOUT);
}
/**
* form 表单提交
*
* @param url 链接
* @param request 请求体
* @param timeout 超时时间
*/
public static <T extends HttpCommonResponse> T postForm(String url, HttpCommonRequest<T> request, int timeout) {
return executeFormRequest(url, request, HttpMethod.POST, timeout);
}
// ==================================== endregion ====================================
// ==================================== region GET方法 ====================================
public static <T extends HttpCommonResponse> T get(String url, HttpCommonRequest<T> request) {
return get(url, request, DEFAULT_TIMEOUT);
}
public static <T extends HttpCommonResponse> T get(String url, HttpCommonRequest<T> request, int timeout) {
return executeJsonRequest(url, request, HttpMethod.GET, timeout);
}
public static <T extends HttpCommonResponse> T get(String url, Class<T> responseType) {
return get(url, responseType, DEFAULT_TIMEOUT);
}
public static <T extends HttpCommonResponse> T get(String url, Class<T> responseType, int timeout) {
return executeEmptyRequest(url, responseType, HttpMethod.GET, timeout);
}
public static <T extends HttpCommonResponse> T getForm(String url, HttpCommonRequest<T> request) {
return getForm(url, request, DEFAULT_TIMEOUT);
}
public static <T extends HttpCommonResponse> T getForm(String url, HttpCommonRequest<T> request, int timeout) {
return executeFormRequest(url, request, HttpMethod.GET, timeout);
}
// ==================================== endregion ====================================
// ==================================== region 无返回值方法 ====================================
public static void post(String url) {
post(url, DEFAULT_TIMEOUT);
}
/**
* 无参无返回
*
* @param url 链接
* @param timeout 超时时间
*/
public static void post(String url, int timeout) {
executeVoidRequest(url, HttpMethod.POST, timeout);
}
public static void get(String url) {
get(url, DEFAULT_TIMEOUT);
}
public static void get(String url, int timeout) {
executeVoidRequest(url, HttpMethod.GET, timeout);
}
// ==================================== endregion ====================================
// ==================================== region 核心执行方法 ====================================
/**
* 执行json请求
*
* @param url 链接
* @param request 入参
* @param method 方法
* @param timeout 超时时间
* @return 自定义出参
*/
private static <T extends HttpCommonResponse> T executeJsonRequest(String url, HttpCommonRequest<T> request,
HttpMethod method, int timeout) {
validateRequest(url, request);
validateTimeout(timeout);
String jsonBody = JSON.toJSONString(request);
logRequestStart(url, jsonBody, method);
HttpRequest httpRequest = createRequest(url, method)
.addHeaders(request.getHeaders())
.body(jsonBody);
return executeAndProcess(httpRequest, jsonBody, request.getResponseClass(), timeout);
}
/**
* 执行空请求(有返回)
*
* @param url 链接
* @param responseType 出参类型
* @param method 方法
* @param timeout 超时时间
* @return 根据出参类型 返回出参
*/
private static <T extends HttpCommonResponse> T executeEmptyRequest(String url, Class<T> responseType,
HttpMethod method, int timeout) {
validateUrl(url);
validateTimeout(timeout);
logRequestStart(url, EMPTY_BODY_LOG, method);
HttpRequest httpRequest = createRequest(url, method);
return executeAndProcess(httpRequest, EMPTY_BODY_LOG, responseType, timeout);
}
/**
* 执行表单提交
*
* @param url 链接
* @param request 入参
* @param method 方法
* @param timeout 超时时间
* @return 自定义出参
*/
private static <T extends HttpCommonResponse> T executeFormRequest(String url, HttpCommonRequest<T> request,
HttpMethod method, int timeout) {
validateRequest(url, request);
validateTimeout(timeout);
Map<String, Object> formParams = request.getParamsFrom();
logRequestStart(url, formParams, method);
HttpRequest httpRequest = createRequest(url, method)
.addHeaders(request.getHeaders())
.form(formParams);
return executeAndProcess(httpRequest, formParams, request.getResponseClass(), timeout);
}
/**
* 执行空请求(无返回)
*
* @param url 链接
* @param method 方法
* @param timeout 超时时间
*/
private static void executeVoidRequest(String url, HttpMethod method, int timeout) {
validateUrl(url);
validateTimeout(timeout);
logRequestStart(url, EMPTY_BODY_LOG, method);
HttpRequest httpRequest = createRequest(url, method);
processVoidResponse(executeRequest(httpRequest, timeout), url);
}
// ==================================== endregion ====================================
// ==================================== region 工具方法 ====================================
/**
* 创建请求体
*
* @param url 链接
* @param method 方法
* @return 请求体
*/
private static HttpRequest createRequest(String url, HttpMethod method) {
validateUrl(url);
return HttpMethod.GET == method ? HttpUtil.createGet(url) : HttpUtil.createPost(url);
}
/**
* 执行请求
*
* @param request 请求体
* @param timeout 超时时间
* @return 请求返回值
*/
private static String executeRequest(HttpRequest request, int timeout) {
return request.timeout(adjustTimeout(timeout)).execute().body();
}
/**
* 执行请求和处理返回
*
* @param request 请求体
* @param params 入参
* @param responseType 出参类型
* @param timeout 超时时间
* @return 自定义出参
*/
private static <T> T executeAndProcess(HttpRequest request, Object params, Class<T> responseType, int timeout) {
String response = executeRequest(request, timeout);
logRequestEnd(request.getUrl(), params, response);
return processResponse(response, request.getUrl(), responseType);
}
/**
* 入参日志记录
*
* @param url 链接
* @param params 入参
* @param method 方法
*/
private static void logRequestStart(String url, Object params, HttpMethod method) {
if (log.isInfoEnabled()) {
String paramStr = params instanceof Map ? JSON.toJSONString(params) : params.toString();
log.info("[HTTP请求开始] 方法: [{}] URL: [{}] 参数: [{}]", method, url, paramStr);
}
}
/**
* 响应日志记录
*
* @param url 链接
* @param params 入参
* @param response 响应体
*/
private static void logRequestEnd(String url, Object params, String response) {
if (log.isInfoEnabled()) {
String paramStr = params instanceof Map ? JSON.toJSONString(params) : params.toString();
log.info("[HTTP请求完成] URL: [{}] 参数: [{}] 响应: [{}]", url, paramStr, response);
}
}
/**
* 解析结果
*
* @param response 响应体
* @return 统一解析体
*/
private static Results<JSONObject> parseResult(String response) {
return JSON.parseObject(response, RESULT_TYPE_REF);
}
/**
* 处理响应体
*
* @param response 响应体
* @param url 链接
* @param responseType 出参类型
* @return 出参实体类
*/
private static <T> T processResponse(String response, String url, Class<T> responseType) {
Results<JSONObject> result = parseResult(response);
validateResult(result, url);
return parseResponse(result.getObj(), responseType);
}
/**
* 处理空响应
*
* @param response 响应体
* @param url 链接
*/
private static void processVoidResponse(String response, String url) {
Results<JSONObject> result = parseResult(response);
validateResult(result, url);
}
/**
* 解析响应
*
* @param data 数据
* @param type 出参类型
* @return 空 或者 出参实体类
*/
private static <T> T parseResponse(JSONObject data, Class<T> type) {
return data != null && type != null ? data.toJavaObject(type) : null;
}
/**
* 调整超时时间
*
* @param timeout 超时时间
* @return 自定义超时时间 或者 最小超时时间
*/
private static int adjustTimeout(int timeout) {
return Math.max(timeout, MIN_TIMEOUT);
}
// ==================================== endregion ====================================
// ==================================== region 验证方法 ====================================
/**
* 验证请求参数
*
* @param url 链接
* @param request 入参
*/
private static void validateRequest(String url, Object request) {
validateUrl(url);
if (request == null) {
throw new IllegalArgumentException("请求参数不能为空");
}
}
/**
* 验证链接
*
* @param url 链接
*/
private static void validateUrl(String url) {
if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException("URL不能为空");
}
}
/**
* 验证自定义超时时间 打日志
*
* @param timeout 超时时间
*/
private static void validateTimeout(int timeout) {
if (timeout < MIN_TIMEOUT) {
log.warn("超时时间 {}ms 过小,已自动调整为最小值 {}ms", timeout, MIN_TIMEOUT);
}
}
/**
* 验证返回结果 如果有问题抛出自定义异常
*
* @param result 返回值
* @param url 链接
*/
private static void validateResult(Results<JSONObject> result, String url) {
if (!Results.SUCCESS.equals(result.getResCode())) {
log.error("接口异常 URL: {} 错误信息: {}", url, result.getMsg());
throw new HttpCommonException(result.getMsg());
}
}
// ==================================== endregion ====================================
/**
* 只有 GET 和 POST 方法
*/
public enum HttpMethod {
POST,
GET
}
// 示例用法
public static void main(String[] args) {
log.info("第一个请求 post 返回正常参数 ==============");
GetUserDto getUserDto = new GetUserDto()
.setUserId("007");
Map<String, String> paramsMap = getUserDto.getParamsMap();
log.info("paramsMap = {}", paramsMap);
GetUserVO getUserVO = HttpUtils.post("http://localhost:8080/api/getUser", getUserDto);
log.info("getUserVO = {}", getUserVO);
log.info("");
try {
log.info("第二个请求 错误请求 404 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser22", getUserDto);
log.info("getUserVO = {}", getUserVO);
} catch (Exception e) {
log.error("第二个请求 错误", e);
}
log.info("");
try {
log.info("第三个请求 错误请求 逻辑错误 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/error", getUserDto);
log.info("getUserVO = {}", getUserVO);
} catch (HttpCommonException e) {
log.error("第三个请求 错误", e);
}
log.info("");
log.info("第四个请求 get 返回 null ==============");
getUserDto = new GetUserDto()
.setUserId("001");
paramsMap = getUserDto.getParamsMap();
log.info("paramsMap = {}", paramsMap);
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser", getUserDto);
log.info("getUserVO = {}", getUserVO);
log.info("");
log.info("第五个请求 post 无入参 有出参 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser2", GetUserVO.class);
log.info("getUserVO = {}", getUserVO);
log.info("");
log.info("第六个请求 post 无入参 无出参 ==============");
HttpUtils.post("http://localhost:8080/api/getUser2");
log.info("");
log.info("第七个请求 post 文件上传 文件上传参数不能为空 ==============");
File file = new File("D:\\project\\test\\src\\main\\resources\\static\\test.png");
UploadFilesDto UploadFilesDto = new UploadFilesDto()
.setUserId("626")
.setFile(file);
Map<String, Object> paramsFrom = UploadFilesDto.getParamsFrom();
log.info("paramsMap = {}", paramsFrom);
UploadFilesVo updateVo = HttpUtils.postForm("http://localhost:8080/api/getFile", UploadFilesDto);
log.info("updateVo = {}", updateVo);
}
}
自定义报错:HttpCommonException
package com.example.test.exception;
public class HttpCommonException extends RuntimeException{
public HttpCommonException() {
super();
}
public HttpCommonException(String s) {
super(s);
}
public HttpCommonException(String message, Throwable cause) {
super(message, cause);
}
public HttpCommonException(Throwable cause) {
super(cause);
}
}
测试
四个实体类:
两个入参:GetUserDto、UploadFilesDto
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Accessors(chain = true)
public class GetUserDto extends HttpCommonRequest<GetUserVO> {
/**
* 其他数据:用户ID
*/
@NotBlank(message = "用户ID 不能为空")
private String userId;
@Override
public Class<GetUserVO> getResponseClass() {
return GetUserVO.class;
}
@Override
protected void setUserParams(Map<String, Object> params) throws IllegalAccessException {
setUserParam(params, this);
}
}
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Accessors(chain = true)
public class UploadFilesDto extends HttpCommonRequest<UploadFilesVo> {
/**
* 文件
*/
private File file;
/**
* 其他数据:用户ID
*/
private String userId;
@Override
public Class<UploadFilesVo> getResponseClass() {
return UploadFilesVo.class;
}
@Override
protected void setUserParams(Map<String, Object> params) throws IllegalAccessException {
setUserParam(params, this);
}
}
两个出参:GetUserVO、UploadFilesVo
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Accessors(chain = true)
public class GetUserVO extends HttpCommonResponse {
/**
* 用户名
*/
private String userName;
/**
* 年龄
*/
private String age;
}
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Accessors(chain = true)
public class UploadFilesVo extends HttpCommonResponse {
/**
* 文件名称
*/
private String fileName;
/**
* 原始文件名
*/
private String originalFilename;
/**
* 其他数据:用户名
*/
private String userName;
}
Controller
@RestController
@Slf4j
@RequestMapping("/api")
public class ApiController {
@RequestMapping("/getUser")
public Results<GetUserVO> getUser(@RequestBody @Validated GetUserDto dto) {
GetUserVO getUserVO = null;
if ("007".equals(dto.getUserId())) {
getUserVO = new GetUserVO()
.setUserName("詹姆斯·邦德")
.setAge("10086");
}
return Results.success(getUserVO);
}
@RequestMapping("/getUser2")
public Results<GetUserVO> getUser2() {
GetUserVO getUserVO = new GetUserVO()
.setUserName("666")
.setAge("777");
return Results.success(getUserVO);
}
@RequestMapping("/error")
public Results error() {
return Results.failed("这里没有逻辑,反正就是失败了");
}
@RequestMapping("/getFile")
public Results<UploadFilesVo> getUser(MultipartFile file, String userId) {
UploadFilesVo uploadFilesVo = new UploadFilesVo();
if ("626".equals(userId)) {
String name = file.getName();
String originalFilename = file.getOriginalFilename();
uploadFilesVo.setUserName("史迪仔")
.setFileName(name)
.setOriginalFilename(originalFilename);
}
return Results.success(uploadFilesVo);
}
}
测试数据:
public static void main(String[] args) {
log.info("第一个请求 post 返回正常参数 ==============");
GetUserDto getUserDto = new GetUserDto()
.setUserId("007");
Map<String, String> paramsMap = getUserDto.getParamsMap();
log.info("paramsMap = {}", paramsMap);
GetUserVO getUserVO = HttpUtils.post("http://localhost:8080/api/getUser", getUserDto);
log.info("getUserVO = {}", getUserVO);
log.info("");
try {
log.info("第二个请求 错误请求 404 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser22", getUserDto);
log.info("getUserVO = {}", getUserVO);
} catch (Exception e) {
log.error("第二个请求 错误", e);
}
log.info("");
try {
log.info("第三个请求 错误请求 逻辑错误 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/error", getUserDto);
log.info("getUserVO = {}", getUserVO);
} catch (HttpCommonException e) {
log.error("第三个请求 错误", e);
}
log.info("");
log.info("第四个请求 get 返回 null ==============");
getUserDto = new GetUserDto()
.setUserId("001");
paramsMap = getUserDto.getParamsMap();
log.info("paramsMap = {}", paramsMap);
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser", getUserDto);
log.info("getUserVO = {}", getUserVO);
log.info("");
log.info("第五个请求 post 无入参 有出参 ==============");
getUserVO = HttpUtils.post("http://localhost:8080/api/getUser2", GetUserVO.class);
log.info("getUserVO = {}", getUserVO);
log.info("");
log.info("第六个请求 post 无入参 无出参 ==============");
HttpUtils.post("http://localhost:8080/api/getUser2");
log.info("");
log.info("第七个请求 post 文件上传 文件上传参数不能为空 ==============");
File file = new File("D:\\project\\test\\src\\main\\resources\\static\\test.png");
UploadFilesDto UploadFilesDto = new UploadFilesDto()
.setUserId("626")
.setFile(file);
Map<String, Object> paramsFrom = UploadFilesDto.getParamsFrom();
log.info("paramsMap = {}", paramsFrom);
UploadFilesVo updateVo = HttpUtils.postForm("http://localhost:8080/api/getFile", UploadFilesDto);
log.info("updateVo = {}", updateVo);
}
测试结果:
11:31:20.928 [main] INFO com.example.test.utils.HttpUtils - 第一个请求 post 返回正常参数 ==============
11:31:20.992 [main] INFO com.example.test.utils.HttpUtils - paramsMap = {userId=007, timestamp=1747193480}
11:31:21.126 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getUser] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}]
11:31:21.545 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/getUser] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}] 响应: [{"resCode":"200","msg":"成功","obj":{"timestamp":1747193481,"userName":"詹姆斯·邦德","age":"10086"}}]
11:31:21.592 [main] INFO com.example.test.utils.HttpUtils - getUserVO = GetUserVO(super=HttpCommonResponse(timestamp=1747193481), userName=詹姆斯·邦德, age=10086)
11:31:21.592 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.592 [main] INFO com.example.test.utils.HttpUtils - 第二个请求 错误请求 404 ==============
11:31:21.593 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getUser22] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}]
11:31:21.631 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/getUser22] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}] 响应: [<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Wed May 14 11:31:21 CST 2025</div><div>There was an unexpected error (type=Not Found, status=404).</div></body></html>]
11:31:21.634 [main] ERROR com.example.test.utils.HttpUtils - 第二个请求 错误
com.alibaba.fastjson.JSONException: syntax error,except start with { or [,but actually start with error
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:684)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:396)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:364)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:278)
at com.example.test.utils.HttpUtils.parseResult(HttpUtils.java:303)
at com.example.test.utils.HttpUtils.processResponse(HttpUtils.java:315)
at com.example.test.utils.HttpUtils.executeAndProcess(HttpUtils.java:264)
at com.example.test.utils.HttpUtils.executeJsonRequest(HttpUtils.java:162)
at com.example.test.utils.HttpUtils.post(HttpUtils.java:54)
at com.example.test.utils.HttpUtils.post(HttpUtils.java:43)
at com.example.test.utils.HttpUtils.main(HttpUtils.java:425)
11:31:21.635 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.635 [main] INFO com.example.test.utils.HttpUtils - 第三个请求 错误请求 逻辑错误 ==============
11:31:21.635 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/error] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}]
11:31:21.642 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/error] 参数: [{"paramsFrom":{"timestamp":"1747193480","userId":"007"},"paramsMap":{"userId":"007","timestamp":"1747193480"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193480,"userId":"007"}] 响应: [{"resCode":"500","msg":"这里没有逻辑,反正就是失败了","obj":null}]
11:31:21.642 [main] ERROR com.example.test.utils.HttpUtils - 接口异常 URL: http://localhost:8080/api/error 错误信息: 这里没有逻辑,反正就是失败了
11:31:21.642 [main] ERROR com.example.test.utils.HttpUtils - 第三个请求 错误
com.example.test.exception.HttpCommonException: 这里没有逻辑,反正就是失败了
at com.example.test.utils.HttpUtils.validateResult(HttpUtils.java:399)
at com.example.test.utils.HttpUtils.processResponse(HttpUtils.java:316)
at com.example.test.utils.HttpUtils.executeAndProcess(HttpUtils.java:264)
at com.example.test.utils.HttpUtils.executeJsonRequest(HttpUtils.java:162)
at com.example.test.utils.HttpUtils.post(HttpUtils.java:54)
at com.example.test.utils.HttpUtils.post(HttpUtils.java:43)
at com.example.test.utils.HttpUtils.main(HttpUtils.java:434)
11:31:21.643 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.643 [main] INFO com.example.test.utils.HttpUtils - 第四个请求 get 返回 null ==============
11:31:21.643 [main] INFO com.example.test.utils.HttpUtils - paramsMap = {userId=001, timestamp=1747193481}
11:31:21.643 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getUser] 参数: [{"paramsFrom":{"timestamp":"1747193481","userId":"001"},"paramsMap":{"userId":"001","timestamp":"1747193481"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193481,"userId":"001"}]
11:31:21.654 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/getUser] 参数: [{"paramsFrom":{"timestamp":"1747193481","userId":"001"},"paramsMap":{"userId":"001","timestamp":"1747193481"},"responseClass":"com.example.test.pojo.vo.GetUserVO","timestamp":1747193481,"userId":"001"}] 响应: [{"resCode":"200","msg":"成功","obj":null}]
11:31:21.654 [main] INFO com.example.test.utils.HttpUtils - getUserVO = null
11:31:21.654 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.654 [main] INFO com.example.test.utils.HttpUtils - 第五个请求 post 无入参 有出参 ==============
11:31:21.655 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getUser2] 参数: [{}]
11:31:21.669 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/getUser2] 参数: [{}] 响应: [{"resCode":"200","msg":"成功","obj":{"timestamp":1747193481,"userName":"666","age":"777"}}]
11:31:21.669 [main] INFO com.example.test.utils.HttpUtils - getUserVO = GetUserVO(super=HttpCommonResponse(timestamp=1747193481), userName=666, age=777)
11:31:21.669 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.669 [main] INFO com.example.test.utils.HttpUtils - 第六个请求 post 无入参 无出参 ==============
11:31:21.669 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getUser2] 参数: [{}]
11:31:21.676 [main] INFO com.example.test.utils.HttpUtils -
11:31:21.676 [main] INFO com.example.test.utils.HttpUtils - 第七个请求 post 文件上传 文件上传参数不能为空 ==============
11:31:21.676 [main] INFO com.example.test.utils.HttpUtils - paramsMap = {file=D:\project\test\src\main\resources\static\test.png, timestamp=1747193481, userId=626}
11:31:21.676 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求开始] 方法: [POST] URL: [http://localhost:8080/api/getFile] 参数: [{"file":"D:\\project\\test\\src\\main\\resources\\static\\test.png","timestamp":"1747193481","userId":"626"}]
11:31:21.802 [main] INFO com.example.test.utils.HttpUtils - [HTTP请求完成] URL: [http://localhost:8080/api/getFile] 参数: [{"file":"D:\\project\\test\\src\\main\\resources\\static\\test.png","timestamp":"1747193481","userId":"626"}] 响应: [{"resCode":"200","msg":"成功","obj":{"timestamp":1747193481,"fileName":"file","originalFilename":"test.png","userName":"史迪仔"}}]
11:31:21.805 [main] INFO com.example.test.utils.HttpUtils - updateVo = UploadFilesVo(super=HttpCommonResponse(timestamp=1747193481), fileName=file, originalFilename=test.png, userName=史迪仔)
进程已结束,退出代码0