ResponseBodyAdvice接口统一controller返回值及@ControllerAdvice统一异常处理
以下有使用到lombok,请自行添加lombok依赖并在idea中添加lombok插件
统一处理类
1.实现ResponseBodyAdvice接口,通过重写beforeBodyWrite方法拦截Controller层的返回值并进行统一封装;
2.添加@ControllerAdvice注解和@ExceptionHandler注解,统一异常处理。可在Controller层之接抛出异常,exceptionHandler方法会进行处理。如果定义了多个@ExceptionHandler,会根据拦截的Exception的继承关系来处理,类似try-catch。
@ControllerAdvice(basePackages = "com.jack.server.controller")
@Slf4j
public class ControllerHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
ResponseVo<Object> responseVo = new ResponseVo<>();
responseVo.setCode(HttpStatus.SC_OK);
responseVo.setMessage("success");
responseVo.setData(o);
return responseVo;
}
@ExceptionHandler(BizException.class)
@ResponseBody
public ResponseVo<Object> exceptionHandler(BizException e) {
log.error(e.getMessage(), e);
ResponseVo<Object> responseVo = new ResponseVo<>();
responseVo.setCode(Integer.valueOf(e.getCode()));
responseVo.setMessage(e.getMessage());
responseVo.setData(e.getCause());
return responseVo;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseVo<Object> exceptionHandler(Exception e) {
log.error(e.getMessage(), e);
ResponseVo<Object> responseVo = new ResponseVo<>();
responseVo.setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
responseVo.setMessage("系统异常");
responseVo.setData(e.getMessage());
return responseVo;
}
注意点:
(1)@SpringBootApplication启动类需要指定scanBasePackages来扫描到该类
(或@ControllerAdvice(annotations={RestController.class, Controller.class}));
(2)@ControllerAdvice需要指定basePackages来扫描到所有Controller;
(3)实现ResponseBodyAdvice接口并将supports方法的返回值设置为true;
(4)@ExceptionHandler底下的@ResponseBody不要漏;
(5)@ExceptionHandler处理异常时,要打印异常日志,不然异常日志会丢失。
结果统一封装类
@Data
public class ResponseVo<T> {
private int code;
private String message;
private T data;
}
自定义业务异常类
@Data
public class BizException extends RuntimeException{
private String code;
private String message;
public BizException(BizExceptionEnum bizExceptionEnum) {
code = bizExceptionEnum.getCode();
message = bizExceptionEnum.getMessage();
}
}
业务异常枚举类
抛自定义业务异常类时使用
@Getter
@AllArgsConstructor
public enum BizExceptionEnum {
SYSTEM_ERROR("1001","系统异常"),
BAD_REQUEST("1002","错误的请求参数"),
NOT_FOUND("1003","找不到请求路径!"),
CONNECTION_ERROR("1004","网络连接请求失败!"),
METHOD_NOT_ALLOWED("1005","不合法的请求方式"),
DATABASE_ERROR("1004","数据库异常"),
BOUND_STATEMENT_NOT_FOUNT("1006","找不到方法!"),
REPEAT_REGISTER("1007","重复注册"),
NO_USER_EXIST("1008","用户不存在"),
INVALID_PASSWORD("1009","密码错误"),
NO_PERMISSION("1010","非法请求!");
private String code;
private String message;
}