简单学了下过滤器,代码如下
@WebFilter(urlPatterns = "/*", filterName = "myFilter")
@Order(1)//设置加载顺序,值越小越先加载,
public class MyFilter implements Filter {
Logger logger = LoggerFactory.getLogger(MyFilter.class);
public static int i = 0;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Boolean flag = SessionUtil.isLogin((HttpServletRequest) request, (HttpServletResponse) response);
if(flag == Boolean.TRUE){
chain.doFilter(request, response);
}else{
i++;
logger.info("用户未登录,将转发到登录页面" + i);
((HttpServletRequest) request ).getRequestDispatcher("login.html").forward(request, response);
}
}
}
使用request进行转发,可以访问到login.html页面
输出结果如下
2021-10-11 21:15:25.351 INFO 20772 --- [nio-8080-exec-1] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面1
2021-10-11 21:15:26.899 INFO 20772 --- [nio-8080-exec-2] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面2
2021-10-11 21:15:26.970 INFO 20772 --- [nio-8080-exec-6] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面3
但是使用重定向访问login.html页面时,即((HttpServletResponse) response).sendRedirect("login.html");却访问不到login.html页面,而且很奇怪。输出结果如下
......
2021-10-11 21:26:23.211 INFO 12840 --- [nio-8080-exec-2] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面78
2021-10-11 21:26:23.214 INFO 12840 --- [nio-8080-exec-9] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面79
2021-10-11 21:26:23.216 INFO 12840 --- [nio-8080-exec-3] com.srtp.administer.filter.MyFilter : 用户未登录,将转发到登录页面80
我猜想的是这样,重定向使的浏览器去访问login.html资源,但是又被过滤器拦截,结果服务器又命令浏览器去访问login.html资源,陷入了一个死循环?
但是使用转发却不一样,转发是服务端去访问加载资源将结果返回给浏览器渲染,因此不会再被过滤器拦截。
这个场景应该使用 sendRedirect ,但是要防止死循环 ,就是在 sendRedirect 之前判断当前页面是否需要 登录认证 ,不需要的话 ,就不sendRedirect
感觉不行吧,因为我是对所有请求进行过滤,使用sendRedirect的话还是会对请求进行拦截,还是会陷入循环。可以将过滤范围缩小,例如只对user/*类型的请求进行拦截过滤,这样使用sendRedirect进行的重定向请求就不会拦截了,感觉应该能行。
@up-bear: 伪码
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if request.url.path.startwith("/login"){
chain.doFilter(request, response);
return;
}
Boolean flag = SessionUtil.isLogin((HttpServletRequest) request, (HttpServletResponse) response);
if(flag == Boolean.TRUE){
chain.doFilter(request, response);
}else{
i++;
logger.info("用户未登录,将转发到登录页面" + i);
((HttpServletRequest) request ).sendRedirect("login.html");
}
}
可以试试拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 注册登录拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/", "/account/login","/account/gologin","/default/index","/assets/**", "/css/**", "/font/**","/font-awesome4.0.3/**","/js/**","/images/**","/avatars/**", "/img/**");
}
}
拦截器实现这个功能确实比过滤器简单,谢谢老哥哦。
建议百度,深入理解下转发和重定向的区别。前者是一个请求,后者是两个请求
--debug 检查更多调试日志
– 快乐的凡人721 3年前