Spring Boot提供了@ControllerAdvice以及@RestControllerAdvice两个注解来实现全局异常监控,再通过@ExceptionHandler注解来标明要监控的异常的类型,这里为了实现同一类处理web和ajax请求出现的异常,使用@RestControllerAdvice
这里定义了一个走定义的异常类DescribeException
,包含自己定义的异常,还定义了一个异常枚举类ExceptionEnum
,储存自己定义的异常。当抛出异常时,抛出DescribeException
来代替,从而简化异常处理的ExceptionHandle
类
ExceptionHandle .class
@RestControllerAdvice
public class ExceptionHandle {
@ExceptionHandler(value = Exception.class)
public Object exceptionGet(Exception e,HttpServletRequest request,HttpServletResponse response) {
//自定义的异常类
DescribeException MyException = null;
//返回前端的数据格式
Result> result = null;
//判断异常是否属于已定义
if (e instanceof DescribeException) {
MyException = (DescribeException) e;
result = ResultUtil.error(MyException.getCode(), MyException.getMessage());
}
//其它再拦截器以及其它无法直接抛出异常的地方抛出的异常只能自己判断,类似与shiro的权限不足异常
else if (e instanceof UnexpectedTypeException) {
}
//上传文件过大异常
else if (e instanceof UnauthorizedException) {
result = ResultUtil.error(ExceptionEnum.UnauthorizedException);
}
//不属于以上所有异常,按未定义异常处理
else {
result = ResultUtil.error(ExceptionEnum.UNKNOW_ERROR);
}
//判断是否为ajax请求,是则返回json格式数据,不是则返回ModelAndView对象
if(isAjax(request)) {
return result;
}
else {
ModelAndView mav = new ModelAndView("error");
mav.addObject("error",result.getMsg());
return mav;
}
}
//判断是否为ajax请求
boolean isAjax(HttpServletRequest request) {
return (request.getHeader("X-Requested-With") != null
&& "XMLHttpRequest".equals(request.getHeader("X-Requested-With").toString()));
}
}
DescribeException.class
public class DescribeException extends RuntimeException{
//错误状态码
private Integer code;
//利用定义的枚举类初始化
public DescribeException(ExceptionEnum exceptionEnum) {
super(exceptionEnum.getMsg());
this.code = exceptionEnum.getCode();
}
//自定义异常
public DescribeException(String message, Integer code) {
super(message);
this.code = code;
}
ExceptionEnum.class
public enum ExceptionEnum {
UNKNOW_ERROR(-1,"未知错误"),
USER_IS_EXIT(-101,"用户已存在"),
AccountIsLocked(1,"账户已被锁定,请60秒以后重试"),
UnauthorizedException(2,"无访问权限")
;
private Integer code;
private String msg;
ExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
(最后附上一个实用的技巧)
一般上线的时候的文件配置和测试时候的配置是不一样的,这时为了防止频繁改变yml文件内容,可以设置多个配置文件,格式如:application-xxx.yml
而在eclipse运行时则在application.yml添加:
spring:
profiles:
active: dev
切换不同的yml文件:
运行的时候在指令后面添加:--spring.profiles.active=xxx
即可实现