SpringMVC统一返回值和全局异常处理的实现
一.SpringMVC统一返回值格式
1. ResponseBodyAdvice的简介
ResponseBodyAdvice是在Controller执行return后,在response返回给前端之前将response拦截,在对response做处理之后再返回给客户端;
ResponseBodyAdvice接口有两个方法,在supperts()中我们可以控制哪些controller或controller中的哪些方法需要进行统一处理,只有supperts()返回true才会执行beforBodyWrite();我们会在beforeWrite()中对response进行处理。
示例如下:
/**
* 全局统一返回结果类
*/
public class GlobalResultHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
//获取控制器名称
String name = Objects.requireNonNull(methodParameter.getMethod()).getName();
List<String> list = Arrays.asList(name);
return !list.contains(name);
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
return Result.ok(o);
}
}
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)来对指定异常进行异常处理;可以添加多个方法来对不同的异常进行不同的处理
最终代码:
/**
* 统一返回模型
*/
@Data
public class Result<T> {
//状态码
private Integer code;
//信息
private String message;
//数据
private T data;
//构造私有化
private Result() {
}
//设置数据,返回对象的方法
public static <T> Result<T> build(T data, ResultCodeEnum resultCodeEnum) {
//创建Resullt对象,设置值,返回对象
Result<T> result = new Result<>();
//判断返回结果中是否需要数据
if (data != null) {
//设置数据到result对象
result.setData(data);
}
//设置其他值
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
//返回设置值之后的对象
return result;
}
//成功的方法
public static <T> Result<T> ok(T data) {
return build(data, ResultCodeEnum.SUCCESS);
}
//失败的方法
public static <T> Result<T> fail(T data) {
return build(data, ResultCodeEnum.FAIL);
}
}
/**
* 全局统一返回结果类and异常处理类
*/
@RestControllerAdvice(basePackages = "com.atguigu.ssyx.controller")
public class GlobalResultHandler implements ResponseBodyAdvice<Object> {
private final static Logger LOGGER = LogFactory.getFactory(GlobalResultHandler.class);
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
//获取控制器名称
String name = Objects.requireNonNull(methodParameter.getMethod()).getName();
List<String> list = Arrays.asList(name);
return !list.contains(name);
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
return Result.ok(o);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(Exception.class)
public Result<String> businessValidate(Exception e) {
LOGGER.error("捕捉异常", e);
return Result.fail(null);
}
}
还没有评论,来说两句吧...