SpringMVC统一返回值和全局异常处理的实现

心已赠人 2023-10-13 14:27 67阅读 0赞

一.SpringMVC统一返回值格式

1. ResponseBodyAdvice的简介
ResponseBodyAdvice是在Controller执行return后,在response返回给前端之前将response拦截,在对response做处理之后再返回给客户端;

ResponseBodyAdvice接口有两个方法,在supperts()中我们可以控制哪些controller或controller中的哪些方法需要进行统一处理,只有supperts()返回true才会执行beforBodyWrite();我们会在beforeWrite()中对response进行处理。

示例如下:

  1. /**
  2. * 全局统一返回结果类
  3. */
  4. public class GlobalResultHandler implements ResponseBodyAdvice<Object> {
  5. @Override
  6. public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
  7. //获取控制器名称
  8. String name = Objects.requireNonNull(methodParameter.getMethod()).getName();
  9. List<String> list = Arrays.asList(name);
  10. return !list.contains(name);
  11. }
  12. @Override
  13. public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
  14. ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
  15. return Result.ok(o);
  16. }
  17. }

2.@RestControllerAdvice的简介

@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成,而@ControllerAdvice继承了@Component,因此@RestControllerAdvice本质上是个Component

@RestControllerAdvice的特点:

(1)通过@ControllerAdvice会作用在所有注解了@RequestMapping的控制器的方法上。可以将对于控制器的全局配置放在同一个位置

(2)注解了@RestControllerAdvice的类的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。

@ExceptionHandler:与@RestControllerAdvice配合使用时,用于全局处理控制器里的异常。value属性可以指定要拦截的异常类型

@InitBinder:与@ControllerAdvice配合使用时,可以用来进行全局数据预处理;注解了@RequestMapping的方法在其执行之前初始化WebDataBinder(数据绑定器),让前台请求参数绑定到Model中

@ModelAttribute:本来作用是绑定键值对到Model中,当与@ControllerAdvice配合使用时,可以让注解了@RequestMapping的方法都可以获得此键值对

(3)@RestControllerAdvice可以通过属性指定Controller范围

@RestControllerAdvice(basePackages={“xxx.xxx”}):指定一个或多个包,这些包及其子包下的所有 Controller 都被该@ControllerAdvice 管理
@RestControllerAdvice(basePackageClasses={xxx.class}):指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该@ControllerAdvice 管理
@RestControllerAdvice(assignableTypes={xxx.class}):指定一个或多个 Controller 类,这些类被该@ControllerAdvice 管理
@ControllerAdvice(annotations = {XXXAnnotation.class}):指定一个或多个注解,被这些注解所标记的 Controller 会被该@ControllerAdvice 管理

二.总结

实体统一返回结果步骤如下:

(1)创建ResponseBodyAdvice的实现类,重写supperts()和beforBodyWrite()

(2)为该实现类加上@RestControllerAdvice注解,通过属性指定需要被@RestControllerAdvice管理的controller

(3)使用supperts()协助我们更加灵活的过滤需要进行统一返回处理的controller

(4)在beforBodyWrite()中进行统一返回处理

实现统一异常处理步骤如下:

(1)创建全局异常处理类

(2)为该实现类加上@RestControllerAdvice注解,通过属性指定需要被@RestControllerAdvice管理的controller

(3)创建异常处理方法,在该方法上添加@ExceptionHandler(XXX.class)来对指定异常进行异常处理;可以添加多个方法来对不同的异常进行不同的处理

最终代码:

  1. /**
  2. * 统一返回模型
  3. */
  4. @Data
  5. public class Result<T> {
  6. //状态码
  7. private Integer code;
  8. //信息
  9. private String message;
  10. //数据
  11. private T data;
  12. //构造私有化
  13. private Result() {
  14. }
  15. //设置数据,返回对象的方法
  16. public static <T> Result<T> build(T data, ResultCodeEnum resultCodeEnum) {
  17. //创建Resullt对象,设置值,返回对象
  18. Result<T> result = new Result<>();
  19. //判断返回结果中是否需要数据
  20. if (data != null) {
  21. //设置数据到result对象
  22. result.setData(data);
  23. }
  24. //设置其他值
  25. result.setCode(resultCodeEnum.getCode());
  26. result.setMessage(resultCodeEnum.getMessage());
  27. //返回设置值之后的对象
  28. return result;
  29. }
  30. //成功的方法
  31. public static <T> Result<T> ok(T data) {
  32. return build(data, ResultCodeEnum.SUCCESS);
  33. }
  34. //失败的方法
  35. public static <T> Result<T> fail(T data) {
  36. return build(data, ResultCodeEnum.FAIL);
  37. }
  38. }
  39. /**
  40. * 全局统一返回结果类and异常处理类
  41. */
  42. @RestControllerAdvice(basePackages = "com.atguigu.ssyx.controller")
  43. public class GlobalResultHandler implements ResponseBodyAdvice<Object> {
  44. private final static Logger LOGGER = LogFactory.getFactory(GlobalResultHandler.class);
  45. @Override
  46. public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
  47. //获取控制器名称
  48. String name = Objects.requireNonNull(methodParameter.getMethod()).getName();
  49. List<String> list = Arrays.asList(name);
  50. return !list.contains(name);
  51. }
  52. @Override
  53. public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
  54. ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
  55. return Result.ok(o);
  56. }
  57. @ResponseStatus(HttpStatus.BAD_REQUEST)
  58. @ExceptionHandler(Exception.class)
  59. public Result<String> businessValidate(Exception e) {
  60. LOGGER.error("捕捉异常", e);
  61. return Result.fail(null);
  62. }
  63. }

发表评论

表情:
评论列表 (有 0 条评论,67人围观)

还没有评论,来说两句吧...

相关阅读