Javaweb 过滤器与重定向的关系

过滤器与重定向的关系

在Web开发中我们经常要写过滤器,现在我们用Javaweb中过滤器Filter(位于 javax.servlet包下)来讨论。

面临需求

做一个请求资源的过滤器,要求登录后的用户并且session没有过期的情况下,任然可以通过直接登录后的页面。

思路:根据需求,我们可以简单的知道只需要在过滤器中,拿到session取登录的用户信息,如果存在,那就表示可以访问;如果没有那就报错,让重新登录。

根据思路,写出代码:

public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse reps = (HttpServletResponse) response;
        HttpSession session = req.getSession();

        // session 中有user的信息
        User user = (User) session.getAttribute(Constant.USER_INFO);
        if (user == null) {
            // reps.sendRedirect("/smbms/error.jsp");
        }
        // 执行链
        chain.doFilter(request, response);

        // 获取请求的文件
       System.out.println(req.getServletPath());
    }

    @Override
    public void destroy() {
    }
}

web.xml配置:

<!--    过滤session中有的登录-->
    <filter>
        <filter-name>Sysfilter</filter-name>
        <filter-class>com.zzx.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Sysfilter</filter-name>
        <url-pattern>/jsp/*</url-pattern>
    </filter-mapping>

测试效果:

第一步:进入主页,复制地址http://localhost:8080/smbms/jsp/frame.jsp ,然后退出(logout中会去除session的user)
在这里插入图片描述

第二步:退出后再次访问,http://localhost:8080/smbms/jsp/frame.jsp

在这里插入图片描述

结果确实是我们想要的,成功了。

思考成功的原因:

在这里插入图片描述

思考一个问题,在user为空的情况下,虽然设置了重定向,但是执行链里面的原来的请求会不会去执行?为了得到这个结果,我们加上

// 获取请求的文件
System.out.println(req.getServletPath());

然后,重新执行测试流程,控制台打印结果如下

/jsp/frame.jsp
/jsp/logout.do
/jsp/frame.jsp

看到这个结果我们知道了执行链会执行,但是疑惑的是,明明请求的是原来的文件地址,咋就变成了 /smbms/error.jsp 这个文件地址?

于是我们来猜测一下原因,在重定向之后原来的请求失效了,导致啥也没去请求

为了验证这个猜测,我们改动一部分代码,

在这里插入图片描述

将重定向这一行注释掉。再次执行测试流程,退出后直接访问

在这里插入图片描述

结果:

在这里插入图片描述

发现进入主页了。

这就证明了我们的猜测,同一个请求进来后,如果发生重定向,那么原来的请求将失效

所以整个执行的流程就是,1、进入过滤器 ->发现session中user是空的 -> 2、重定向到错误页面(客户端发起了一个新的请求) -> 3、执行链doFilter(由于没有可用的请求目标,不做访问,直接下一步) -> 4、过滤器完成

对于控制台打印的请求文件,为什么没有error.jsp,原因是这样的,(1)重定向是客户端发起的新的一次请求,与本次请求无关,所以没有在这次过滤中打印。(2)重定向的请求error.jsp 的文件路径,没有配置在这个过滤器的过滤请求路径里面,所以不会打印。

// 获取请求的文件
System.out.println(req.getServletPath());

对于上面的解释,我们可以知道,既然重定向之后,原来的请求路径会失效,那就没必要让执行链 去执行 原来的请求路径;只有当原来的路径有效的时候,才去让执行链执行。

所以程序可以优化如下:

public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse reps = (HttpServletResponse) response;
        HttpSession session = req.getSession();

        User user = (User) session.getAttribute(Constant.USER_INFO);
        // session 中有user的信息
        if (user == null) {
            reps.sendRedirect("/smbms/error.jsp");
        } else {
            // 加上else 优化一下
            chain.doFilter(request, response);
        }

    }

    @Override
    public void destroy() {
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值