springBoot的过滤器,监听器,拦截器
概述
在开发中,我们经常要考虑一些问题,对敏感词进行过滤,用户是否已经登录,是否需要对他的请求进行拦截,或者领导问现在在线人数有多少人?我们如何实现这些功能哪
@WebFilter
package com.xmlxy.firstspringbootproject; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "customFilter",urlPatterns = "/*")
public class CustomFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(CustomFilter.class); @Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("===========拦截器初始化==========");
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
log.info("doFilter请求处理");
} @Override
public void destroy() {
log.info("fifter销毁");
}
}
在application类中添加@ServletComponentScan注解
package com; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.PropertySource; @SpringBootApplication
@ServletComponentScan
@PropertySource(value = "classpath:jdbc.properties",encoding = "utf-8")
public class FirstSpringbootProjectApplication { public static void main(String[] args) {
SpringApplication.run(FirstSpringbootProjectApplication.class, args);
} }
运行结果

(笔误,应该是过滤器初始化)过滤器已经生效,但若有多个过滤器,无法指定执行顺序,我们可以通过Java类的名称,从A-L,按顺序执行。但这种方式毕竟不大靠谱,所以,有第二种写法,它提供setOrder函数,为filter设置排序值。
package com.xmlxy.service; import com.xmlxy.firstspringbootproject.CustomFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class WebFilterConfig
{
@Bean
public FilterRegistrationBean someFilterRegistration1()
{
FilterRegistrationBean registration = new FilterRegistrationBean<>();
System.out.println("我执行了。。。。。。。");
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration; } }
我们尝试写个demo,验证一下过滤器是否执行。
用户登录对象
User.java
package com.xmlxy.bean; import lombok.Data;
import org.springframework.stereotype.Component; @Data
@Component
public class User {
private String user;
private String pwd;
}
登录控制
LoginController.java
package com.xmlxy.firstspringbootproject; import com.xmlxy.bean.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; @RestController
public class LoginController { @RequestMapping(value = "login",method = RequestMethod.GET)
public String login(HttpServletRequest request)
{
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
HttpSession session = request.getSession();
if ("admin".equals(user) && "admin".equals(pwd))
{
User user1 = new User();
user1.setUser(user);
user1.setPwd(pwd);
session.setAttribute("user",user1);
return "登录成功";
}
return "密码错误,登录失败";
}
@RequestMapping(value = "test",method = RequestMethod.GET)
public String test()
{
return "test接口";
}
}
过滤器
CustomFilter.java
package com.xmlxy.firstspringbootproject; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
//@WebFilter(filterName = "customFilter",urlPatterns = "/*")
public class CustomFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(CustomFilter.class); String includes[] = {"/login","register"}; @Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("===========过滤器初始化==========");
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
HttpSession session = request.getSession(false);
String uri = request.getRequestURI();
boolean flag = isNeedFilter(uri);
if (!flag)
{
filterChain.doFilter(servletRequest,servletResponse);
System.err.printf("登录成功");
}else {
if (session != null && session.getAttribute("user") != null)
{
filterChain.doFilter(servletRequest,servletResponse);
}else {
System.err.printf("暂时未登录");
}
} log.info("doFilter请求处理");
}
public boolean isNeedFilter(String uri)
{
for (String include:includes)
{
if (include.equals(uri))
{
return false;
}
}
return true;
}
@Override
public void destroy() {
log.info("fifter销毁");
}
}
过滤器配置
WebFilterConfig
package com.xmlxy.service; import com.xmlxy.firstspringbootproject.CustomFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class WebFilterConfig
{
@Bean
public FilterRegistrationBean someFilterRegistration1()
{
FilterRegistrationBean registration = new FilterRegistrationBean<>();
System.out.println("我执行了。。。。。。。");
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
return registration;
}
}
运行测试。。访问 127.0.0.1/test 控制台

访问 http://127.0.0.1:8080/login?user=admin&pwd=admin,可以看到登录成功

在次访问 127.0.0.1/test 页面显示

所以,我们的过滤器成功过滤未登录的用户
监听器
正在你为自己会了过滤用户自鸣得意时,你的组长过来了,小明,你看下我们平台的在线用户有多少人。如果不知道监听器童鞋,是否会在登录接口处每次登录成功都+1,然而这种统计结果是不准确的,因为用户如果反复登录退出,那这个在值就远远大于实际值,最后就面临着,加班在加班的悲惨下场。
CustomLister.java
package com.xmlxy.firstspringbootproject; import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; @WebFilter
public class CustomLister implements HttpSessionListener
{
public static int online = 0; @Override
public void sessionCreated(HttpSessionEvent sessionEvent)
{
System.out.println("创建session,统计在线人数");
online ++;
} @Override
public void sessionDestroyed(HttpSessionEvent sessionEvent)
{
System.out.println("session已经销毁");
}
}
配置监听器配置,在刚才的WebFilterConfig.java添加
@Bean
public ServletListenerRegistrationBean listenerRegistrationBean()
{
ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
srb.setListener(new CustomLister());
System.out.println("");
return srb;
}
添加一个访问在线人数的接口
@RequestMapping(value = "onLinePerson",method = RequestMethod.GET)
public String onLinePerson()
{
StringBuffer stringBuffer = new StringBuffer("");
stringBuffer.append(" 在线人数 ");
stringBuffer.append(CustomLister.online);
stringBuffer.append(" 个人 ");
return stringBuffer.toString();
}
访问127.0.0.1/onLinePerson,发现被拦截器拦截了,我们先登录。在查看接口

换个浏览器,调用下login接口,在查看

拦截器
拦截器,个人理解,在web上有些像是过滤器的补充,它能更精确的控制拦截哪些函数或者字段,在拦截之前或之后做一些操作。我们现在做一个敏感词的拦截,其实这个操作放在过滤器操作也是可以的,但lz因为刚才把拦截用户的操作放在过滤器了,在大规模更改,lz觉得没必要,因为都是大同小异。
CustomInterceptor.java
package com.xmlxy.firstspringbootproject; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter; public class CustomInterceptor implements HandlerInterceptor
{
private static final Logger log = LoggerFactory.getLogger(CustomInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {
log.info("=======拦截器被调用=====");
String url = request.getRequestURI();
if (url != null && url.indexOf("seqing") != -1)
{
PrintWriter printWriter = response.getWriter();
printWriter.write("ming gan ci");
return false;
}
log.info("返回false 则中断请求");
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
{
log.info("请求后调用");
} @Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception e)
{
log.info("视图渲染完回调");
}
}
配置拦截
package com.xmlxy.service; import com.xmlxy.firstspringbootproject.CustomFilter;
import com.xmlxy.firstspringbootproject.CustomInterceptor;
import com.xmlxy.firstspringbootproject.CustomLister;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class WebFilterConfig implements WebMvcConfigurer
{
@Bean
public FilterRegistrationBean someFilterRegistration1()
{
FilterRegistrationBean registration = new FilterRegistrationBean<>();
System.out.println("我执行了。。。。。。。");
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
return registration;
} @Bean
public ServletListenerRegistrationBean listenerRegistrationBean()
{
ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
srb.setListener(new CustomLister());
return srb;
} @Override
public void addInterceptors(InterceptorRegistry registry)
{
/*拦截规则*/
registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/*");
} }
现在测试访问127.0.0.1/seqing,被过滤,要求先登录。我们调用登录接口后,再次调用,发现被拦截了

看下日志调用,可以发现,拦截器是在访问接口前被调用的

过滤器,拦截器区别
这里主要说下拦截器和过滤器的区别和使用场景,通过demo可以发现,它们都能实现权限的检查,日志记录这些功能,主要说下它们的区别
- 过滤器和拦截器触发的时机是不同的,在进入servlet之前,过滤器就进行预处理了。而拦截器是在调用Controller之前才触发执行,过滤器的范围较广,对所有的请求都起作用,而拦截起只 对action起作用

2.拦截器可以获取IOC容器的各个bean,而过滤器就不行。因为拦截器是spring提供管理的,也因此拦截器可以使用spring的任何资源。
3.拦截器是利用Java反射机制实现,过滤器是函数的回调。因此实现方式是不同的。
三者使用场景
监听器:常用统计在线用户,统计网站的访问量,记录用户的访问路径
过滤器:过滤敏感词,权限访问控制
拦截器:权限验证,判断用户是否登录等
springBoot的过滤器,监听器,拦截器的更多相关文章
- springboot(五)过滤器和拦截器
前言 过滤器和拦截器二者都是AOP编程思想的提现,都能实现诸如权限检查.日志记录等.二者有一定的相似之处,不同的地方在于: Filter是servlet规范,只能用在Web程序中,而拦截器是Sprin ...
- JavaWeb过滤器.监听器.拦截器-原理&区别-个人总结
对比项 拦截器 过滤器 机制 反射机制 函数回调 是否依赖servlet容器 是 否 请求处理 只能对action请求起作用 几乎所有的请求起作用 对action处理 可以访问action上下文.值栈 ...
- JavaWeb过滤器.监听器.拦截器-原理&区别(转)
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...
- AOP,过滤器,监听器,拦截器【转载】
面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承.多态和封装.而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配 ...
- JavaWeb过滤器.监听器.拦截器-?原理&区别
过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇. 1.拦截器是基于java的反射机制,过 ...
- 过滤器 & 监听器 & 拦截器
过滤器: https://blog.csdn.net/MissEel/article/details/79351231 https://blog.csdn.net/qq_32363305/articl ...
- SpringBoot(十一)过滤器和拦截器
v博客前言 在做web开发的时候,过滤器(Filter)和拦截器(Interceptor)很常见,通俗的讲,过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想 ...
- springboot使用过滤器和拦截器
1.Filter过滤器 @Componentpublic class AuthFilter implements Filter { private static final Log log = Log ...
- springboot配置过滤器和拦截器
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Http ...
- 关于springboot中过滤器和拦截器
在解决跨域问题中,发现拦截器和过滤器用得不是熟练.就参考了下一下两个作者的文档.希望大家也可以汲取精华 文档1 https://blog.csdn.net/moonpure/article/det ...
随机推荐
- Protobuf 小试牛刀
本文以PHP为例. 环境: CentOS 6.8 proto 3.8 PHP 7.1.12 PHP protobuf扩展 3.8.0 go1.12.5 linux/amd64 本文示例仓库地址: ht ...
- Unity AssetBundle,Asset,GameObject之间的联系
一.问题 首先,这里说明一下,我这边的GameObject有点笼统,就是表达的是游戏中的具体实例. 二.概念 1)Asset是什么? 游戏中具体的资源,像texture,mesh,material,s ...
- 【Netty整理02-详细使用】Netty入门
重新整理版:https://blog.csdn.net/the_fool_/article/details/83002152 参考资料: 官方文档:http://netty.io/wiki/user- ...
- Asp.net HttpClient Proxy(Fiddler)
<system.net> <defaultProxy> <proxy bypassonlocal="False" usesystemdefault=& ...
- Java连载3-编译与运行阶段详解&JRE,JDK,JVM关系
·一. 1.JDK下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk12-downloads-5295953.html ...
- 201907 TIOBE 编程语言排行榜-Python坐稳第三
目录 一.编程语言7月排行榜 二.Top10编程语言指数走势(2002-2018) 三.历史排名(1988-2019) 四.编程语言"名人榜"( 2003-2018) 五.Top2 ...
- django基础知识之定义模板:
定义模板 模板语言包括 变量 标签 { % 代码块 % } 过滤器 注释{# 代码或html #} 变量 语法: {{ variable }} 当模版引擎遇到一个变量,将计算这个变量,然后将结果输出 ...
- django基础知识之定义模型:
定义模型 在模型中定义属性,会生成表中的字段 django根据属性的类型确定以下信息: 当前选择的数据库支持字段的类型 渲染管理表单时使用的默认html控件 在管理站点最低限度的验证 django会为 ...
- .Net知识大全(个人整理)
.Net知识大全 本章内容适用于对.NET有一定基础的或者是想通过本文章对.NET基础知识记不清楚的朋友,可以通过本文章进行回顾. 面试的时候可能也会遇到相应的题目,建议面试前进行回顾!!! 1.NE ...
- 数字IC前后端设计中的时序收敛(二)--Setup违反的修复方法
本文转自:自己的微信公众号<数字集成电路设计及EDA教程> 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具的教程. 考虑到微信公众 ...