SpringBoot的filter过滤器

一、过滤器的作用和概述

1.1 简述

人—>检票员filter—> 电影院。

注意配置多个filter的时候要设置编号id值越小优先级越高越先执行。

在3.0之后新增@WebFilter注解当使用注解配置多个Filter时用户无法控制其执行顺序此时Filter过滤的顺序是按照Filter的类名来控制的按自然排序的规则。
在这里插入图片描述

1.2 使用场景

场景权限控制、用户登录(非前端后端分离场景)等过滤非法登录

二、自定义过滤的两种方式

2.1 第一种方式

1.启动类里面增加 @ServletComponentScan进行扫描
2.新建一个Filter类implements Filter实现对应的接口
3. @WebFilter 标记一个filter类被spring进行扫描
                        urlPatterns拦截规则支持正则
4.控制chain.doFilter的方法的调用来实现是否通过放行还是不放行
            如果放行 FilterChain.dofilter(res,rep);
            如果不放行调转到指定页面web应用resp.sendRedirect("/index.html"); return

2.1.1 启动类增加注解@ServletComponentScan

package com.bjpowernode.springbootfilter01;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * SpringBoot整合filter   方式一
 */
@ServletComponentScan
@SpringBootApplication
public class SpringbootFilter01Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootFilter01Application.class, args);
    }

}

2.1.2 定义一个filter类

package com.bjpowernode.springbootfilter01.filter;

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

import java.util.logging.LogRecord;

/**
 *SpringBoot整合Filter 方式一
 *<filter>
 *	<filter-name>FirstFilter</filter-name>
 *	<filter-class>com.bjpowernode.filter.FirstFilter</filter-class>
 *</filter>
 *<filter-mapping>
 *	<filter-name>FirstFilter</filter-name>
 *	<url-pattern>/first</url-pattern>
 *</filter-mapping>
 */
@WebFilter(filterName = "FirstFilter",urlPatterns = "/first")
public class LoginFilter implements Filter {
    public boolean isLoggable(LogRecord record) {
        return false;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException, IOException {
        System.out.println("进入Filter");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("离开Filter");
    }

    @Override
    public void destroy() {

    }



}

2.1.3. 测试

浏览器访问localhost:8080/first
在这里插入图片描述

在这里插入图片描述

2.2 第二种方式

2.2.1 自定义fitler类

package com.bjpowernode.springbootfilter02.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
 *
 *SpringBoot整合Filter 方式二
 *
 */
public class SecondFilter implements Filter {
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        System.out.println("进入SecondFilter");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("离开SecondFilter");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
}

2.2.4 在启动类中进行配置

package com.bjpowernode.springbootfilter02;

import com.bjpowernode.springbootfilter02.filter.SecondFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

/**
 * SpringBoot整合Filter方式二
 */
@SpringBootApplication
public class SpringbootFilter02Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootFilter02Application.class, args);
    }

    /**
     * 注册Filter
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new SecondFilter());
        //filterRegistrationBean.addUrlPatterns(new String[]{"*.do","*.jsp"});
        filterRegistrationBean.addUrlPatterns("/second");
        return filterRegistrationBean;
    }
}


2.4.3 第二种方式的另一种写法

将启动类配置@Bean的部分提取到专门的配置类中并用 @Autowired注入SecondFilter对象所以在传参数的时候就不用new SecondFilter对象了

package com.bjpowernode.springbootfilter02_1.config;

import com.bjpowernode.springbootfilter02_1.filter.SecondFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfiger implements WebMvcConfigurer {

    @Autowired
    private SecondFilter secondFilter;

    /**
     * 注册Filter
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
//        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new SecondFilter());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(secondFilter);

        //filterRegistrationBean.addUrlPatterns(new String[]{"*.do","*.jsp"});
        filterRegistrationBean.addUrlPatterns("/second");
        return filterRegistrationBean;
    }
}

因为要有@Autowired注解注入SecondFilter对象所以SecondFilter需要交给Spring容器管理所以需要在SecondFilter加上一个@Component注解才能被spring容器扫描到
在这里插入图片描述

2.4.4. 测试

浏览器访问localhost:8080/second
在这里插入图片描述
在这里插入图片描述

2.3 过滤器的小案例

2.3.1 场景描述

自定义一个过滤器对路径中含有api字样且userName为xm的请求则放过进行否则其他情况进行拦截。

浏览器访问实例http://localhost:8080/api/showUserName?userName=xm

2.3.2 Controller层

package com.bjpowernode.springbootfilter03logindemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@Controller
public class UserController {

    @RequestMapping("/api/showUserName")
    public String showName(String userName, Model model){
        System.out.println("进入controller层了"+userName);
        model.addAttribute("userName",userName);
        return "index";//跳转到指定页面
    }
}

2.3.3 启动类 添加注解@ServletComponentScan //添加过滤器使用

package com.bjpowernode.springbootfilter03logindemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * 场景描述
 * 自定义一个过滤器对路径中含有api字样且userName为xm的请求则放过进行否则其他情况进行拦截。
 */
@ServletComponentScan //添加过滤器使用
@SpringBootApplication
public class SpringbootFilter03LogindemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootFilter03LogindemoApplication.class, args);
        System.out.println("用户登录=====");
    }

}

2.3.4自定义过滤器类UserLoginFilter.java

package com.bjpowernode.springbootfilter03logindemo.filter;


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

/**
 *SpringBoot整合Filter 方式一
 *<filter>
 *	<filter-name>loginFilter</filter-name>
 *	<filter-class>com.ljf.spring.boot.demo.spt.filter.filter.UserLoginFilter</filter-class>
 *</filter>
 *<filter-mapping>
 *	<filter-name>loginFilter</filter-name>
 *	<url-pattern>/api/*</url-pattern>
 *</filter-mapping>
 */
@WebFilter(urlPatterns = "/api/*",filterName = "loginFilter")
public class UserLoginFilter implements Filter {
package com.bjpowernode.springbootfilter03logindemo.filter;


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

/**
 *SpringBoot整合Filter 方式一
 *<filter>
 *	<filter-name>loginFilter</filter-name>
 *	<filter-class>com.ljf.spring.boot.demo.spt.filter.filter.UserLoginFilter</filter-class>
 *</filter>
 *<filter-mapping>
 *	<filter-name>loginFilter</filter-name>
 *	<url-pattern>/api/*</url-pattern>
 *</filter-mapping>
 */
@WebFilter(urlPatterns = "/api/*",filterName = "loginFilter")
public class UserLoginFilter implements Filter {

    /*
    *容器加载的时候调用
    */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("=================init loginFilter=============");
    }

    /*
    *请求被拦截的时候进行调用
    */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String userName = req.getParameter("userName");
        System.out.println("获取用户名"+userName);
        if("xm".equals(userName)){
            System.out.println("用户名正确");
            System.out.println("===========");
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            System.out.println("用户名错误");
            System.out.println("跳转到登录页面");
            resp.sendRedirect("/login.html");//重定向不到templates目录下页面必须走后端一下跳转到指定页面才行
//            req.getRequestDispatcher("/").forward(req,resp);
            return;
        }
    }

    /**
     * 容器被销毁的时候被调用
     */
    @Override
    public void destroy() {
        System.out.println("=========================destroy loginFilter=====================");
    }
}

如果满足浏览器的访问实例http://localhost:8080/api/showUserName?userName=xm则跳转到templates下面的index.html页面

2.3.5 templates下的index页面

在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
templates下的index页面
<td th:text="${userName}">/td>
</body>
</html>

如果不满足浏览器的访问实例http://localhost:8080/api/showUserName?userName=xm则重定向到static下的login.html

2.3.6被拦截后重定向的页面

static下的login.html
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登录页面-----------------------------static!!!
</body>
</html>

2.3.7 测试

项目启动

在这里插入图片描述

1.请求url含有api且userName=xm放行通过
进入filter中
在这里插入图片描述

在这里插入图片描述

2.请求url含有api且userName=xsfdsf拦截过滤跳转到login.html页面
在这里插入图片描述

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring