前言
过滤器中抛出的异常是无法被全局异常处理器所处理的,因此需要去处理过滤器中的异常时需要额外的去进行配置。
解决方法
直接说我的解决方法,将过滤器中的错误信息封装之request中转发到自定义的错误处理控制类,在控制类中重新抛出异常。
BizException自定义业务异常
首先定义一个自定义异常,继承RuntimeException,定义自定义异常的好处是可以更灵活的处理异常,如密码错误,用户未登录,用户登录过期等。
@Getter
public class BizException extends RuntimeException {
private static final long serialVersionUID = -3229475403587709519L;
/**
* 自定义异常枚举类
**/
private ExceptionCodeEnum error;
private String msg;
/**
* 将捕获的异常转换为自定义业务异常
**/
public BizException(ExceptionCodeEnum error, Throwable cause) {
super(cause);
this.error = error;
this.msg = error.getMsg();
}
public BizException(ExceptionCodeEnum error) {
this.error = error;
}
public BizException(ExceptionCodeEnum error,String msg) {
this.error = ExceptionCodeEnum.ERROR;
this.msg = msg;
}
}
ExceptionCodeEnum自定义异常枚举类
通过枚举类可以灵活的定义常用的错误,例如用户密码错误、用户不存在等。
@Getter
public enum ExceptionCodeEnum {
/**
* 用户异常
*/
TOKEN_EXPIRED(40001, "长时间未操作,请重新登录!");
ExceptionCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
在过滤器中的模拟抛出异常
通过try catch 捕获异常后转发到错误控制类中
try{
throw new Exception();
}catch (Excepotion e){
// 将错误信息封装在request中,使用定义好的枚举类信息
request.setAttribute("message", ExceptionCodeEnum.TOKEN_EXPIRED);
// 请求转发到错误控制类中
request.getRequestDispatcher("/errorCustom").forward(request, response);
return;
}
错误控制类
将错误在这里进行处理。
@RestController
public class ErrorController {
/**
* 接收过滤器的异常重新抛出异常
*/
@GetMapping ("/errorCustom")
public void rethrow(ServletRequest request) {
// 获取异常信息
Object message = request.getAttribute("message");
//获取request中的message后,重新抛出异常
throw new BizException((ExceptionCodeEnum) message);
}
}
总结
在处理过滤器中的异常时,可以通过写一个自定义错误控制器,将错误转发到该控制器中,再进行错误处理。