SpringBoot的filter过滤器
SpringBoot的filter过滤器
目录
- SpringBoot的filter过滤器
- 一、过滤器的作用和概述
- 1.1 简述
- 1.2 使用场景
- 二、自定义过滤的两种方式
- 2.1 第一种方式
- 2.1.1 启动类增加注解@ServletComponentScan
- 2.1.2 定义一个filter类
- 2.1.3. 测试
- 2.2 第二种方式
- 2.2.1 自定义fitler类
- 2.2.4 在启动类中进行配置
- 2.4.3 第二种方式的另一种写法
- 2.4.4. 测试
- 2.3 过滤器的小案例
- 2.3.1 场景描述
- 2.3.2 Controller层
- 2.3.3 启动类 添加注解:@ServletComponentScan //添加过滤器使用
- 2.3.4自定义过滤器类UserLoginFilter.java
- 2.3.5 templates下的index页面
- 2.3.6被拦截后重定向的页面
- 2.3.7 测试
一、过滤器的作用和概述
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页面