登录验证-Filter入门

黑马程序员JavaWeb开发教程

一、Filter- 入门

1.1 概述

  1. 概念:Filter过滤器,是javaWeb三大组件(Servlet、Filter、Listener)之一。
  2. 过滤器可以吧对资源的请求拦截下来,从而实现一些特殊功能
  3. 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

1.2 快速入门

  1. 定义Filter:定义一个类,实现Filter接口,并重写其所有方法。
  2. 配置Filter:Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan开启Servlet组件支持。

1.3 实现

  1. 新建文件夹filter,下创建类DemoFilter,直线Filter接口
    在这里插入图片描述

  2. DemoFilter 中的代码

package com.itheima.mytlias.filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

// Filter类上加@WebFilter注解,配置拦截资源的路径。
@WebFilter(urlPatterns = "/*")//代表拦截所有请求
public class DemoFilter implements Filter {
    @Override//初始化方法,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init,初始化方法执行了");
    }

    @Override//拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
    }

    @Override//销毁方法,只调用一次
    public void destroy() {
        System.out.println("destory,销毁方法执行了");
    }
}

  1. 引导类(MytliasApplication)上加@ServletComponentScan开启Servlet组件支持。
    在这里插入图片描述
  2. 运行程序
    • 初始化方法只执行一次
      在这里插入图片描述
      - 每刷新一次页面就会拦截到一次请求,但是由于拦截请求中只有输出信息的语句,所以除了输出信息之外不会做别的事情
      在这里插入图片描述
      • 关闭本次程序执行会,销毁方法执行,仅执行一次
        在这里插入图片描述

二、详解

2.1 执行流程

2.1.1 执行流程

  1. 浏览器向 web服务器发送请求
  2. 过滤器执行放行前逻辑
  3. 过滤器放行
  4. 访问Web资源,回到过滤器,之后如果有需要可以执行一段放行之后的逻辑
  5. 最后将数据响应给浏览器
    在这里插入图片描述

2.1.2 疑问回答

  1. 放行后访问对应资源,资源访问完成之后,还会回到filter中吗?(会)
  2. 如果回到Filter中是重新执行还是执行放行之后的逻辑?(执行放行之后的逻辑)

2.2 拦截路径

  • Filter可以根据需求,配置不同的拦截资源路径
  1. 拦截具体路径
    • urlPatterns值:/login
    • 含义:只有访问/login路径时,才会被拦截
  2. 目录拦截
    • urlPatterns值:/emps/*
    • 含义:访问/emps下的所有资源,都会被拦截
  3. 拦截所有
    • urlPatterns值:/*
    • 含义:访问所有资源,都会被拦截

2.3 过滤器链

  1. 介绍:一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链
  2. 顺序:注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序
    在这里插入图片描述

三、登录校验-Filter

3.1 步骤

  1. 获取请求url
  2. 判断请求url是否包含login,如果包含,说明是登录操作,放行
  3. 获取请求头中的令牌(token)
  4. 判断令牌是否存在,如果不存在返回错误结果(未登录)
  5. 解析token,如果解析失败,返回错误结果(未登录)
  6. 放行

3.2 代码

package com.example.demo.filter;


import com.alibaba.fastjson.JSONObject;
import com.example.demo.pojo.Result;
import com.example.demo.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1. 获取请求的url
        String url = request.getRequestURL().toString();
        log.info("请求的url {}", url);
        //2. 判断请求的url中是否包含login,如果包含,说明是登录操作,直接放行
        if (url.contains("login")) {
            log.info("登录操作,放行");
            filterChain.doFilter(servletRequest, servletResponse);
            return;//直接放行,后边的代码不用再执行了
        }
        //3. 获取请求头中的令牌(token)
        String jwt = request.getHeader("token");
        //4. 判断令牌是否存在,如果不存在,返回错误结果
        if (jwt.length() == 0) {
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--JSON 阿里巴巴fastjson(在pom中引入相应的依赖)
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return;
        }
        //5. 解析令牌token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析失败,返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--JSON 阿里巴巴fastjson(在pom中引入相应的依赖)
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return;

        }
        //6. 放行
        log.info("令牌合法,放行");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

3.3 运行结果

在这里插入图片描述

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值