springboot返回统一的标准格式
定义注解
package com.yaoling.annotation;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseResult {
}
controller层引入注解
@RestController
@RequestMapping(value = "/material/api/v1/laboratoryWarehouse/")
@ResponseResult //引入注解
public class LaboratoryWarehouseController {
....
统一返回Response类编写
枚举类
public enum ResultCode {
SUCCESS(200, "成功"),
FAILED(500, "失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限");
private int code;
private String message;
ResultCode(int code,String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
返回类
@Data
public class Response<T> {
private int code;
private String description;
private T result;
private String expandMsg;
public Response(int code, String description, T data) {
this.code = code;
this.description = description;
this.result = data;
}
public static <T> Response<T> success(String description) {
return new Response<T>(ResultCode.SUCCESS.getCode(), description, null);
}
public static <T> Response<T> success(T data) {
return new Response<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
public static <T> Response<T> success(T data, String description) {
return new Response<T>(ResultCode.SUCCESS.getCode(), description, data);
}
public static <T> Response<T> forbidden(T data) {
return new Response<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
}
public static <T> Response<T> error(T data) {
return new Response<T>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMessage(), data);
}
public static <T> Response<T> error(String description) {
return new Response<T>(ResultCode.FAILED.getCode(), description, null);
}
public static <T> Response<T> error(String description, T data) {
return new Response<T>(ResultCode.FAILED.getCode(), description, data);
}
}
定义拦截器
执行链组件
@Component
public class ResponseResultInterceptor implements HandlerInterceptor {
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
Class<?> beanType = ((HandlerMethod) handler).getBeanType();
Method method = ((HandlerMethod) handler).getMethod();
//方法或class上有ResponseResult注解的,request设置属性
if (beanType.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, beanType.getAnnotation(ResponseResult.class));
} else if (method.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANN, method.getAnnotation(ResponseResult.class));
}
}
return true;
}
}
自定义拦截器
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
ResponseResultInterceptor interceptor = new ResponseResultInterceptor();
registry.addInterceptor(interceptor);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
定义controller切面
@ControllerAdvice
public class ResponseResultHandler<T> implements ResponseBodyAdvice<Object> {
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra == null) {
return false;
}
//判断是否有RESPONSE_RESULT_ANN属性==>判断是否有引入ResponseResult注解
HttpServletRequest sraRequest = sra.getRequest();
ResponseResult responseResult = (ResponseResult) sraRequest.getAttribute(RESPONSE_RESULT_ANN);
return responseResult != null;
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
//返回body中有页码
if (body instanceof PageInfoVo) {
List<T> data = (List<T>) ((PageInfoVo<T>) body).getData();
int size = data.size();
//list中有数据
if (size > 0) {
ObjectMapper objectMapper = new ObjectMapper();
List<Object> snakeList = new ArrayList<>(size);
for (T datum : data) {
//object转JsonNode
JsonNode jsonNode = objectMapper.readTree(objectMapper.writeValueAsString(datum));
//JsonNode的key转为蛇形
JsonNode snakeJsonNode = JsonUtils.convertKeysToSnake(jsonNode);
snakeList.add(snakeJsonNode);
}
((PageInfoVo<T>) body).setData((List<? extends T>) snakeList);
}
return Response.success(body);
}
//判断返回的body数据
if (body instanceof Response) {
return body;
} else if (body instanceof String) {
return Response.success(body);
}
return Response.success(body);
}
}
测试
接口
public class LaboratoryWarehouseController {
@Autowired
private LaboratoryWarehouseService service;
@RequestMapping(method = RequestMethod.GET, value = "query")
public PageInfoVo<BaseMaterVo> query(@RequestBody BaseMaterialDto baseMaterialDto) {
//此时的返回类型为PageInfoVo<BaseMaterVo>
return service.query(baseMaterialDto);
}
}
接口结果
{
"code": 200,
"description": "成功",
"result": {
"pagination": {
"total": 1,
"totalPage": 1,
"page": 1,
"pageSize": 20
},
"data": [
{
"id": "573024997631591394",
"name": "环辛烷",
"code": "WL0028958",
"batch_no": "20231206-001",
"laboratory": null,
"preparation_date": null,
"warehouse_entry_time": "2023-12-06 00:00:00"
}
]
},
"expandMsg": null
}