首页 新闻 会员 周边 捐助

Java过滤器

0
[已解决问题] 解决于 2021-11-15 15:56

简单学了下过滤器,代码如下

@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资源,陷入了一个死循环?
但是使用转发却不一样,转发是服务端去访问加载资源将结果返回给浏览器渲染,因此不会再被过滤器拦截。

up-bear的主页 up-bear | 初学一级 | 园豆:134
提问于:2021-10-11 21:30

--debug 检查更多调试日志

快乐的凡人721 3年前
< >
分享
最佳答案
0

这个场景应该使用 sendRedirect ,但是要防止死循环 ,就是在 sendRedirect 之前判断当前页面是否需要 登录认证 ,不需要的话 ,就不sendRedirect

奖励园豆:5
地菜 | 菜鸟二级 |园豆:208 | 2021-10-12 09:35

感觉不行吧,因为我是对所有请求进行过滤,使用sendRedirect的话还是会对请求进行拦截,还是会陷入循环。可以将过滤范围缩小,例如只对user/*类型的请求进行拦截过滤,这样使用sendRedirect进行的重定向请求就不会拦截了,感觉应该能行。

up-bear | 园豆:134 (初学一级) | 2021-10-12 20:58

@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");
}
}

地菜 | 园豆:208 (菜鸟二级) | 2021-10-13 09:06
其他回答(2)
0

可以试试拦截器

@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/**");
    }
}
楠木大叔 | 园豆:2083 (老鸟四级) | 2021-10-12 13:08

拦截器实现这个功能确实比过滤器简单,谢谢老哥哦。

支持(0) 反对(0) up-bear | 园豆:134 (初学一级) | 2021-10-12 23:19
0

建议百度,深入理解下转发和重定向的区别。前者是一个请求,后者是两个请求

素手揽清风 | 园豆:229 (菜鸟二级) | 2021-10-15 17:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册