springboot封装统一返回

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
}
posted @ 2023-12-20 10:40  Scott_pb  阅读(346)  评论(0编辑  收藏  举报