过滤器filter和拦截器interceptor,并分别实现登录认证功能

        过滤器(Filter)和拦截器(Interceptor)是在Web开发中常用的两种概念,用于对HTTP请求和响应进行处理和控制。它们通常用于实现一些通用的功能,比如身份验证、日志记录、安全性检查等。

1、二者的不同点:

过滤器更适用于基于Servlet的应用,而拦截器则更适合于使用Spring MVC的项目

  • 过滤器是Servlet规范提供的一种机制,主要用于在HTTP请求和响应的处理过程中进行拦截和处理。过滤器可以对请求和响应进行修改、增加或删除一些属性、头信息等。它们可以用于全局的过程,比如在请求进入Servlet之前进行预处理,或者在响应返回给客户端之前进行后处理。
  • 拦截器是Spring框架提供的一种机制,用于在Spring MVC框架中对HTTP请求进行拦截和处理。拦截器可以更细粒度地控制请求的处理流程,例如在进入Controller之前或之后执行一些操作。
2、Filter
使用步骤:
1)定义Filter:定义一个类,实现Filter接口,并重写其所有方法。

这里以实现登陆验证功能为例:

@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//      将通用的 ServletRequest 转换为 HttpServletRequest
        HttpServletRequest req = (HttpServletRequest) servletRequest;
//      将通用的 ServletResponse 转换为 HttpServletResponse
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

//        1、获取请求url
        String url = req.getRequestURI().toString();

//        2、判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if (url.contains("login")){
            //放行操作
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }

//        3、获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

//        4、判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (!StringUtils.hasLength(jwt)){
            Result error = Result.error("NOT LOGIN");
            //手动转换,将对象转换为json格式 <-----阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            //将该字符串响应给前端
            resp.getWriter().write(notLogin);
            return;
        }
//        5、解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){//解析失败
            e.printStackTrace();
            Result error = Result.error("NOT LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }
//        6、放行。
        filterChain.doFilter(servletRequest,servletResponse);

    }
}

        首先,在过滤器中实现 doFilter 方法时,通常需要对传入的请求(ServletRequest)和响应(ServletResponse)进行类型转换,以便能够使用更多的 Servlet API 功能。所以这里的前两行代码将通用的 ServletRequestServletResponse 转换为 HttpServletRequestHttpServletResponse,以便可以访问更丰富的 HTTP 请求和响应的功能。

        之后按照登录认证的五步走:1、获取请求url;2、判断请求url中是否包含login,如果包含,说明是登录操作,放行;3、获取请求头中的令牌(此处我的指定令牌名为token);4、判断令牌是否存在,如果不存在,返回错误结果(未登录);5、解析token,如果解析失败,返回错误结果(未登录)。

        其中JwtUtils是用于实现jwt生成和解码的工具类,前一篇文章有写。

2)配置Filter:

        Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan开启Servlet组件支持。

        @WebFilter注解用于对过滤器进行配置,其后的(urlPatterns = "/*")是指定要拦截的URL模式,"/*"代表拦截全部。

3、Interceptor
1)定义Interceptor:定义一个类,实现Interceptor接口,并重写其preHandle方法

同样以实现登陆验证功能为例:

@Component
public class LoginCheckinterceptor implements HandlerInterceptor {
    //快捷键ctrl+o 对方法进行重写
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //目标资源方法执行前执行,返回true:放行,返回false:不放行

        //        1、获取请求url
        String url = req.getRequestURI().toString();

//        2、判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if (url.contains("login")){
            //放行操作
            return true;
        }

//        3、获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

//        4、判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (!StringUtils.hasLength(jwt)){
            Result error = Result.error("NOT LOGIN");
            //手动转换,将对象转换为json格式 <-----阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            //将该字符串响应给前端
            resp.getWriter().write(notLogin);
            return false;
        }
//        5、解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){//解析失败
            e.printStackTrace();
            Result error = Result.error("NOT LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }
//        6、放行。
        return true;
    }

    @Override//目标资源方法执行后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}
4、方法重写方面需注意

在 Java Web 开发中,Filter 和 Interceptor 都是用于处理请求和响应的中间件,但它们在使用和实现方面有一些区别。

Filter
  • 在 Java Servlet 规范中,Filter 是一个标准的接口,为处理请求和响应提供了通用的方式。
  • Filter 需要实现 javax.servlet.Filter 接口,它有三个主要方法:initdoFilterdestroy
  • doFilter 方法是必须要实现的,用于编写过滤逻辑。可以对请求和响应进行修改或处理。
  • Filter 的方法需要显式地调用 chain.doFilter(request, response) 来继续请求链的处理。

Interceptor
  • 在 Spring MVC 中,Interceptor 是 Spring 框架提供的一种机制,用于处理请求和响应。
  • Interceptor 需要实现 org.springframework.web.servlet.HandlerInterceptor 接口,它有三个方法:preHandlepostHandleafterCompletion
  • 我们需要根据需要重写这些方法来实现预处理、后处理和完成处理逻辑。
  • Interceptor 的方法不需要显式地调用下一个拦截器或处理链。

猜你喜欢

转载自blog.csdn.net/LuoluoluoluoYan/article/details/132346093