根据springmvc架构,filter中抛出的异常无法被全局异常处理器捕获,这里利用路由转发,在controller中抛出异常
filter类:
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response =(HttpServletResponse)servletResponse;
//获取URI
String requestURI = request.getRequestURI();
//不需要处理的路径
String[] urls = new String[] {
"/api/user/login"
};
//检测请求是否需要处理
boolean check = check(urls, requestURI);
//如果不需要处理
if(check) {
log.info("无需处理{}",requestURI);
filterChain.doFilter(request,response);
return;
}
//判断登录状态,如果登录就放行
if (request.getSession().getAttribute(USER_LOGIN_STATE) != null) {
log.info("用户已经登陆:{}",request.getSession().getAttribute(USER_LOGIN_STATE));
filterChain.doFilter(request,response);
return;
} else {
//未登录抛异常
request.setAttribute("exception", new BusinessException(ErrorCode.NULL_ERROR, "未登录"));
request.getRequestDispatcher("/error/login").forward(request, response);
}
}
/**
* 路径匹配,检查请求是否需要放行
* @param requestURI
* @param urls
* @return
*/
public boolean check(String[] urls, String requestURI) {
for(String url: urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match) {
return true;
}
}
return false;
}
}
转发消息值ErrorController,在其方法内部抛出异常,从而使全局异常处理器捕获
@RestController
@RequestMapping("/error")
public class ErrorController {
@PostMapping("/login")
public BaseResponse<Integer> throwException(HttpServletRequest request) throws Exception {
throw new BusinessException(ErrorCode.NULL_ERROR, "未登录");
}
}