黑马瑞吉外卖练手项目中关于登录过滤用拦截器实现的问题

一:过滤器实现

代码不用多说 B站课程有详解,老师用的就是这个 代码如下:

@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;

        //1、获取本次请求的URI
        String requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}",requestURI);

        //定义不需要处理的请求路径
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };


        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);

        //3、如果不需要处理,则直接放行
        if(check){
            log.info("本次请求{}不需要处理",requestURI);
            filterChain.doFilter(request,response);
            return;
        }

        //4、判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);
            return;
        }

        log.info("用户未登录");
        //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;

    }

    /**
     * 路径匹配,检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @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;
    }
}

二:拦截器实现

首先自己写一个拦截器类 LoginHandlerInterceptor,去实现HandlerInterceptor这个接口,然后重写里面的preHandle方法。

我的代码如下:

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object employee = request.getSession().getAttribute("employee");
        if(employee != null) {
            return true;
        }else {
            System.out.println("saaaaaas");
            response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
            //response.sendRedirect("/backend/page/login/login.html");
            System.out.println("拦截到请求:"+request.getRequestURI());
            return false;
        }
    }
}

 然后去自己的WebMvcConfig类中注册这个拦截器类LoginHandlerInterceptor

代码如下:

 @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/employee/login",
                "/employee/logout","/backend/**","/front/**");
    }

测试后:效果和老师的一样,未登录访问首页后会先看到首页然后跳转到登录页.

但是访问不存在的地址会返回一个json字符串(这是符合逻辑的,这个json数据没被转化可能时前端vue的一些问题,暂时不太清楚原理)如下图所示

检查控制台发现下图

这个请求时404为啥不显示404错误的界面而是把json字符串显示出来,不清楚原因 .

*上面的做法感觉欠妥,拦截后应该是看不到界面,而是直接跳转到登录界面,可以用重定向的方式实现

三:拦截器重定向实现

需改动代码如下:

拦截路劲也需要改动

测试结果:未登录状态下无论输入地址(除了登录页)都会重定向登录页

这种方法有一个bug:

但我们登录后退出来的时输入/backend/index.html这个地址会直接显示首页,检查发现下图

这个可能是缓冲造成的

这种情况下再输入/backend/index.html会正常的重定向到首页

此时的请求为正常的重定向

具体原因未知:

自己写的都有漏洞,知识有限,无法解决

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值