springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现

简介: 这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。

导言

一、过滤器

  1. 过滤器是什么?
    它是基于Servlet 技术实现的, 简单的来说,过滤器就是起到过滤的作用,在web项目开发中帮我们过滤一些指定的 url做一些特殊的处理。 过滤器主要做什么?

    • 过滤掉一些不需要的东西,例如一些错误的请求。
    • 也可以修改请求和相应的内容。
    • 也可以拿来过滤未登录用户
  2. 过滤器的代码实现
    过滤器(filter)有三个方法,其中初始化(init)摧毁(destroy)方法一般不会用到,主要用到的是doFilter这个方法。

  3. 怎么过滤呢?
    如果过滤通过,则在doFilter 执行 filterChain.doFilter(request,response);

二、 创建项目springboot-filter

  1. 根据 springboot 学习二:springboot 第一次创建 web 项目,打包项目并测试成功 博文,快速创建本项目:springboot-filter
  2. 项目依赖仅勾选web即可。
    在这里插入图片描述
  3. 项目结构如下:(记得修改application配置文件的后缀为 yml,我这里忘改了)
    在这里插入图片描述

三、Filter 快速入门

那么在springBoot中如何使用过滤器呢?

自定义Filter有两种实现方式,第一种是使用@WebFilter,第二种是使用 FilterRegistrationBean,下面我们分别来实现

1. @WebFilter 实现

@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。

属性名 类型 描述
filterName String 指定该Filter的名称
urlPatterns String 指定该Filter所拦截的URL。
value String 与 urlPatterns 一致

a. 创建一个MyFilter.java实现Filter接口

package com.feng.springboot_filter.filter;

import org.springframework.core.annotation.Order;

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

@WebFilter(urlPatterns = "/api/*", filterName = "myFilter")
@Order(1) //指定过滤器的执行顺序,值越大越靠后执行
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化过滤器");
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        System.out.println("拦截器 MyFilter 拦截了请求:" + requestURI + ",方法为:" + method);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
AI 代码解读

b. 启动类加上 @ServletComponentScan 注解

在这里插入图片描述

c. 创建一个 FilterController 接口

package com.feng.springboot_filter.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class FilterController {

    @GetMapping("/user/filter")
    public String hello(){
        return "已经通过了过滤器";
    }

}
AI 代码解读

d. 创建一个 TestController 接口

package com.feng.springboot_filter.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/test")
    public String hello(){
        return "hello world";
    }
}
AI 代码解读

e. 项目结构

在这里插入图片描述

f. 测试

i、拦截的请求

http://localhost:8080/api/user/filter
在这里插入图片描述
在这里插入图片描述

ii、未拦截的请求:没有走过滤器

http://localhost:8080/test
在这里插入图片描述
没有走过滤器
在这里插入图片描述

2、FilterRegistrationBean 实现

a、创建 FilterConfig 配置类

package com.feng.springboot_filter.config;

import com.feng.springboot_filter.filter.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public MyFilter myFilter() {
        return new MyFilter();
    }

    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(MyFilter myFilter) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        /**
         * 设置过滤器
         */
        filterRegistrationBean.setFilter(myFilter());
        /**
         * 拦截路径
         */
        filterRegistrationBean.addUrlPatterns("/api/*");
        /**
         * 设置名称
         */
        filterRegistrationBean.setName("myFilter");
        /**
         * 设置访问优先级 值越小越高
         */
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
}
AI 代码解读

b、修改 MyFilter.java

//@WebFilter(urlPatterns = "/api/*", filterName = "myFilter")
AI 代码解读

c、修改启动类

//@ServletComponentScan
AI 代码解读

d、测试

结果和三.1.e一样,说明这两种方式都可以。

i、拦截的请求

http://localhost:8080/api/user/filter
在这里插入图片描述
在这里插入图片描述

ii、未拦截的请求:没有走过滤器

http://localhost:8080/test
在这里插入图片描述
在这里插入图片描述

四、过滤校验用户是否登录实战

采用第二种方式进行 过滤用户是否登录成功

1. 修改 application.yml

修改 application.properties 加入开发接口通配地址

#凡是请求地址层级带有 open 都放行
open:
  url: /**/open/**
AI 代码解读

2. 修改 MyFilter

package com.feng.springboot_filter.filter;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;

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

//@WebFilter(urlPatterns = "/api/*", filterName = "myFilter")
@Order(1) //指定过滤器的执行顺序,值越大越靠后执行
public class MyFilter implements Filter {

    @Value("${open.url}")
    private String openUrl;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化过滤器");
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        System.out.println("拦截器 MyFilter 拦截了请求:" + requestURI + ",方法为:" + method);

        // 首先校验是否是开放 api
        // 是则:直接放行,否则:再校验token
        PathMatcher matcher = new AntPathMatcher();
        if (matcher.match(openUrl, requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            String token = request.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                // 若无 token,则转发到:未登录请求
                servletRequest.getRequestDispatcher("/api/open/unLogin").forward(servletRequest, servletResponse);
            } else {
                // 若有 则放行
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
        //filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
AI 代码解读

3. 新增 未登录接口、首页接口

a、新增接口

    @GetMapping("/open/home/info")
    public Map<String, String> getHome() {
        Map<String, String> map = new HashMap<>();
        map.put("游客", "欢迎访问首页");
        return map;
    }

    @GetMapping("/open/unLogin")
    public String getUnauthorized() {
        return "登录失效,请重新登录";
    }
AI 代码解读

b、全部接口

package com.feng.springboot_filter.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class FilterController {

    @GetMapping("/user/filter")
    public String hello() {
        return "已经通过了过滤器";
    }

    @GetMapping("/open/home/info")
    public Map<String, String> getHome() {
        Map<String, String> map = new HashMap<>();
        map.put("游客", "欢迎访问首页");
        return map;
    }

    @GetMapping("/open/unLogin")
    public String getUnauthorized() {
        return "登录失效,请重新登录";
    }
}
AI 代码解读

4. 测试

  1. 首先访问 开放接口
    http://localhost:8080/api/user/filter(直接放行)
    在这里插入图片描述

  2. 访问需权鉴接口:http://localhost:8080/api/user/filter

    • 不带 token
      在这里插入图片描述

    • 带上 token
      在这里插入图片描述

目录
打赏
0
0
0
0
49
分享
相关文章
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
42 6
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
357 12
Spring Security 入门
Spring Security 是 Spring 框架中的安全模块,提供强大的认证和授权功能,支持防止常见攻击(如 CSRF 和会话固定攻击)。它通过过滤器链拦截请求,核心概念包括认证、授权和自定义过滤器。配置方面,涉及密码加密、用户信息服务、认证提供者及过滤器链设置。示例代码展示了如何配置登录、注销、CSRF防护等。常见问题包括循环重定向、静态资源被拦截和登录失败未返回错误信息,解决方法需确保路径正确和添加错误提示逻辑。
Spring Security 入门
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
82 8
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
355 7
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
101 6
Spring Boot 入门:简化 Java Web 开发的强大工具
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
208 5
从入门到精通---深入剖析Spring DAO
在Java企业级开发中,Spring框架以其强大的功能和灵活性,成为众多开发者的首选。Spring DAO(Data Access Object)作为Spring框架中处理数据访问的重要模块,对JDBC进行了抽象封装,极大地简化了数据访问异常的处理,并能统一管理JDBC事务。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring DAO,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
34 1
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
84 5
学习Spring框架特性及jiar包下载
Spring 5作为最新版本,更新了JDK基线至8,修订了核心框架,增强了反射和接口功能,支持响应式编程及Kotlin语言,引入了函数式Web框架,并提升了测试功能。Spring框架可在其官网下载,包括文档、jar包和XML Schema文档,适用于Java SE和Java EE项目。
46 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等