ResponseBodyAdvice修改Controller返回值

为了实现判断Controller方法上是否有 JsonResult 注解并修改返回值类型为 Result,我们可以通过实现 ResponseBodyAdvice 接口完成此操作。

  1. 创建一个类并实现 ResponseBodyAdvice 接口:
@RestControllerAdvice
public class ResultResponseAdvice implements ResponseBodyAdvice<Object> {
   //...
}
  1. 实现 supports 方法,判断返回值类型是否需要修改。如果返回 true,则执行 beforeBodyWrite 方法;如果返回 false,则不执行。
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return returnType.getMethodAnnotation(JsonResult.class) != null;
}
  1. 实现 beforeBodyWrite 方法,将返回值类型转换为 Result
@RestControllerAdvice
public class JsonResultAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return returnType.getMethodAnnotation(JsonResult.class) != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result) return new JSONObject(body);
        JsonResult anno = returnType.getMethodAnnotation(JsonResult.class);
        int code = anno.code();
        String message = anno.message();
        Result result = new Result().setCode(code).setMessage(message).setData(body);
        return new JSONObject(result);
    }
}
  1. Result 类的实现
@Data
@Accessors(chain = true)
public class Result {
    private int code;
    private Object data;
    private String message;
}
  1. JsonResult注解的实现
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonResult {
    int code() default 0;
    String message() default "success";
    @AliasFor("message")
    String value() default "success";
}

上述代码中,ResultResponseAdvice 类实现了 ResponseBodyAdvice 接口,并被 @RestControllerAdvice 注解标记为全局控制器通知。supports 方法判断方法上是否有 JsonResult 注解,如果有则返回 true,否则返回 false。beforeBodyWrite 方法将返回值类型转换为 Result

最后,我们将 Result 类作为返回值的封装类,将原返回值作为其 data 属性返回,同时可以通过 code 和 message 属性设置返回状态码和信息。

示例:

@GetMapping("/get/simple")
@JsonView(UserView.Simple.class)
@JsonResult
public UserDto getSimple() {
    return userDto;
}
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "yimin",
    "age": 20,
    "createTime": "2023-05-26T15:35:20.243"
  },
  "message": "success"
}
@GetMapping("/get/simple")
@JsonView(UserView.Simple.class)
@JsonResult("这是返回的user信息")
public UserDto getSimple() {
    return userDto;
}
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "yimin",
    "age": 20,
    "createTime": "2023-05-26T15:34:07.795"
  },
  "message": "这是返回的user信息"
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容