过滤器和拦截器的使用及管理

news2024/12/26 23:31:28

参考:

  • (70条消息) Spring过滤器和拦截器的区别_yjc0403的博客-CSDN博客

  • https://www.cnblogs.com/colin220/p/9606412.htm

概述

过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符

拦截器:是在面向切面编程的,就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作

从具体实现区分

  • 过滤器是servlet的

  • 拦截器是spring aop

细节区别

①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。

②拦截器不依赖于servlet容器,过滤器依赖于servlet容器

③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑

关系和工作流程

执行日志

INFO [nio-9018-exec-2] cubeFilter : CubeFilter...进入cube 过滤器

INFO [nio-9018-exec-2] cubeFilter : CubeFilter...过滤器 验证cube权限

INFO [nio-9018-exec-2] cubeFilter : demo service impl

INFO [nio-9018-exec-2] LoginInterceptor : LoginInterceptor...进入拦截器 preHandle

INFO [nio-9018-exec-2] DemoController : DemoController... demo 1 ok

INFO [nio-9018-exec-2] LoginInterceptor : LoginInterceptor...进入拦截器 postHandle

INFO [nio-9018-exec-2] cubeFilter : CubeFilter...退出cube过滤器

代码

过滤器管理

package com.lq.filesystem.filter;

import lombok.extern.log4j.Log4j2;

import org.springframework.web.context.WebApplicationContext;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

@Log4j2

public class MangerFilter implements Filter {

private SsoFilter ssoFilter = new SsoFilter();

private WebApplicationContext wac;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

wac = (WebApplicationContext) filterConfig.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;

String from = httpRequest.getHeader("from");

if ("cube".equals(from)) {

CubeFilter cubeFiler = CubeFilter.getInstance();

cubeFiler.setWac(wac);

cubeFiler.doFilter(request, response, chain);

} else if ("sso".equals(from)) {

ssoFilter.doFilter(request, response, chain);

} else if ("wx".equals(from)) {

WxFilter instance = WxFilter.getInstance();

instance.doFilter(request, response, chain);

} else {

chain.doFilter(request, response);

}

}

}

cube 过滤器

package com.lq.filesystem.filter;

import com.lq.filesystem.service.DemoService;

import com.sun.istack.internal.NotNull;

import org.springframework.web.context.WebApplicationContext;

import javax.servlet.*;

import java.io.IOException;

import java.util.logging.Logger;

public class CubeFilter implements Filter {

Logger log = Logger.getLogger("cubeFilter");

private static final CubeFilter INSTANCE = new CubeFilter();

private WebApplicationContext wac;

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

log.info("CubeFilter...进入cube 过滤器");

log.info("CubeFilter...过滤器 验证cube权限");

if (wac == null) {

throw new ServletException("请设置 WebApplicationContext ");

}

DemoService demoService = wac.getBean(DemoService.class);

log.info(demoService.getT());

chain.doFilter(request, response);

log.info("CubeFilter...退出cube过滤器");

}

public void setWac(@NotNull WebApplicationContext wac) {

this.wac = wac;

}

public static CubeFilter getInstance() {

return INSTANCE;

}

private CubeFilter() {

}

}

sso 过滤器

package com.lq.filesystem.filter;

import javax.servlet.*;

import java.io.IOException;

import java.util.logging.Logger;

public class SsoFilter implements Filter {

Logger log = Logger.getLogger("SsoFilter");

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

log.info("进入sso 拦截器");

log.info("验证sso权限");

chain.doFilter(request, response);

log.info("退出sso拦截器");

}

}

拦截器

package com.lq.filesystem.interceptor;

import com.alibaba.fastjson.JSONObject;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;

import com.auth0.jwt.exceptions.SignatureVerificationException;

import com.auth0.jwt.exceptions.TokenExpiredException;

import com.lq.filesystem.config.StoreProperties;

import com.lq.filesystem.utils.JwtUtil;

import lombok.extern.log4j.Log4j2;

import org.apache.catalina.realm.MemoryRuleSet;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.util.StringUtils;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.logging.Logger;

/**

* @author seven

* @version 1.0

* @description 登录拦截,通过jwt校验

* @date 2022/10/30 21:32

*/

@Component

@Log4j2

public class LoginInterceptor implements HandlerInterceptor {

Logger log = Logger.getLogger("LoginInterceptor");

/**

* 拦截器,在进入controller之前被调用

* 返回 ture 则继续通行,flase 则将不会被继续处理

*/

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

log.info("LoginInterceptor...进入拦截器 preHandle");

final String jwt = request.getHeader("jwt");

JSONObject userError = new JSONObject();

if (!StringUtils.isEmpty(jwt)) {

try {

JwtUtil.verify(jwt);

return true;

}catch (SignatureVerificationException e) {

userError.put("msg","无效签名");

} catch (TokenExpiredException e) {

userError.put("msg","token过期");

} catch (AlgorithmMismatchException e) {

userError.put("msg","token算法不一致");

} catch (Exception e) {

userError.put("msg","其他异常");

}

}else {

userError.put("msg","未携带jwt信息");

// todo 暂时不拦截

return true;

}

userError.put("code",1001);

response.setContentType("application/json;charset=UTF-8");

response.getWriter().println(userError);

return false;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

log.info("LoginInterceptor...进入拦截器 postHandle");

}

}

web 配置,设置过滤器和拦截器

package com.lq.filesystem.config;

import com.lq.filesystem.filter.MangerFilter;

import com.lq.filesystem.interceptor.LoginInterceptor;

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.InterceptorRegistration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**

* @author seven

* @version 1.0

* @description web config

* @date 2022/10/30 21:38

*/

@Configuration

public class WebConfig implements WebMvcConfigurer {

@Autowired

private LoginInterceptor loginInterceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

//注册TestInterceptor拦截器

InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);

registration.addPathPatterns("/**"); //所有路径都被拦截

registration.excludePathPatterns( //添加不拦截路径

"/**/*.html", //html静态资源

"/**/*.js", //js静态资源

"/**/*.css", //css静态资源

"/demo/x/**"

);

}

// 生成一个过滤器bean对象,交过spring管理

@Bean

public FilterRegistrationBean MangerFilter() {

FilterRegistrationBean registration = new FilterRegistrationBean(new MangerFilter());

registration.addUrlPatterns("/demo/*");

registration.setName("mangerFilter");

registration.setOrder(1);

return registration;

}

}

注意事项

  • 在Filter中是无法直接使用Srping容器中的bean的,因此不要使用@autowrite @resource 等获取bean对象,可以通过传进来的上线问对象获取bean

  • 如果希望按照某些条件使用指定的Filter,就不要把Filter交给Spring管理(如果在Filter上加上@Compont等注解,spring会托管这个Filter,代理为ApplicationFilterConfig,进入 chain中),否则直接Filer都会执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Anaconda安装之后Spyder打不开解决办法--目前有用 jupyter notebook 无法正常运行2023.1.7

纯纯小白,探索一天,终于成功,需要我的经历没有白费,让大家少走弯路。 问题描述 从官网下载Anaconda之后,安装,一切正常。打开Anaconda navigator在弹出窗口选择了更新(我怀疑这就根源&#xf…

Js逆向教程24-作用域和自执行函数

作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 Js逆向教程24-作用域和自执行函数 一、变量作用域 1.1局部变量 function jb() {var a"我是局部变量"return a; }1.2全局变…

【Java寒假打卡】Java基础-异常

【Java寒假打卡】Java基础-异常异常概述throws声明异常throw抛出异常try-catch 抛出异常throwable的成员方法异常概述 Exception:称之为异常类,他表示程序本身可以处理的问题 RuntimeException及其子类:运行时异常。(空指针异常,…

JUC总结系列篇 (二) : 对线程的理解和使用总结

文章内容: 一.为什么需要多线程 二.线程的创建 三.线程的方法sleep(),run(),wait(),yeid(),join(),interrupt()等方法归纳总结 四.线程的状态及其转换 五.线程的交替执行案例 六.多个线程依次执行案例 七.多线程并发带来的线程安全问题 一.为什么需要多线程&#x…

Linux项目自动化构建工具-make/Makefile

一、前言 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件…

前端入门笔记 04 —— Web(html CSS)布局

响应式布局 屏幕尺寸变化,需要响应式网页设计RWD web页面适应不同屏幕宽度因素 液态站点,拉伸充满浏览器窗口 小屏幕挤成一团,大屏幕空白间隙过大固定宽度 像素为单位固定尺寸 小屏幕滚动,大屏幕空白 实现 设置meta标签媒体查…

数据结构入门5-1(数和二叉树)

目录 注 树和二叉树的定义 树的定义 树的基本术语 二叉树的定义 树和二叉树的抽象数据类型定义 二叉树的性质和存储结构 二叉树的性质 二叉树的存储结构 1. 顺序存储结构 2. 链式存储结构 遍历二叉树和线索二叉树 遍历二叉树(traversing binary tree&a…

加密与安全

目录 一、编码算法 1.1、ASCII 1.1.1、ASCII简介 1.1.2、ASCII产生原因 1.1.3、表达方式 1.1.4、标准表 1.1.5、大小规则 1.2、Unicode 1.2.1简介 1.2.2编码和实现 1.3、汉字编码 1.3.1、GB2312-80 标准 1.3.2、GBK 编码标准 1.3.3、GB18030编码标准 1.4、URL编…

【Node】中Express框架连接Mysql实现用户注册接口

Node.js中Express框架连接Mysql实现用户注册接口 处理用户注册接口简单分为三步: 1、注册校验 2、完善逻辑 3、拆分模块 拆分模块能够使部分功能能够复用,封装好各个模块使得模块间只能通过有限的接口互相访问,从而降低耦合,拆分模…

LeetCode[1046]最后一块石头的重量

难度&#xff1a;简单 题目&#xff1a; 有一堆石头&#xff0c;每块石头的重量都是正整数。每一回合&#xff0c;从中选出两块最重的 石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果如下&#xff1a;如果 x …

『年度总结』时光如梭 | 再见 2022 | 你好 2023

⭐创作时间2022年12月31日⭐ ✨结果一直到现在才发&#xff0c;说真的写年度总结还是第一次写比较不熟练&#xff0c;去年有这个活动也有佬叫我参加&#xff0c;不过没参加。今年想着有时间来写下的&#xff0c;结果写到现在才发&#xff0c;这东西说真的挺难写的&#…

机器视觉(九):图像配准

目录&#xff1a; 机器视觉&#xff08;一&#xff09;&#xff1a;概述 机器视觉&#xff08;二&#xff09;&#xff1a;机器视觉硬件技术 机器视觉&#xff08;三&#xff09;&#xff1a;摄像机标定技术 机器视觉&#xff08;四&#xff09;&#xff1a;空域图像增强 …

python简单爬虫

爬虫真是一件有意思的事儿啊&#xff0c;之前写过爬虫&#xff0c;用的是urllib2、BeautifulSoup实现简单爬虫&#xff0c;scrapy也有实现过。最近想更好的学习爬虫&#xff0c;那么就尽可能的做记录吧。这篇博客就我今天的一个学习过程写写吧。 一 正则表达式 正则表达式是一…

格式化电脑重装系统怎么操作

​电脑一但中毒的电脑必须重装系统&#xff0c;而且需要格式化后重装系统&#xff0c;才能将病毒铲除&#xff0c;那么如何将电脑格式化后重装系统呢&#xff1f;能够实现电脑格式化重装系统的方法是U盘重装和光盘重装&#xff0c;由于部分电脑没有光驱&#xff0c;建议用U盘&a…

Redis常见集群方案

Redis常见集群方案 Redis集群方案目前主流的有三种&#xff0c;分别是Twemproxy、Codis和Redis Cluster。 Redis Cluster Redis Cluster 集群是去中心化通过客户端分片的结构&#xff0c;集群元数据信息分布在每个节点上&#xff0c;主备切换依赖于多个节点协商选主。 Red…

C++11之lambda表达式

文章目录一、引入原因二、lambda 表达式的语法1. lambda 表达式各部分说明2.捕捉列表说明三、lambda 表达式的本质一、引入原因 如果待排序元素为自定义类型&#xff0c;需要用户定义排序时的比较规则。 比如&#xff1a; struct Goods {string _name; // 名字double _pr…

idea调试npm、tomcat远程服务(包括docker部署方式)

前言 idea调试npm、tomcat远程服务&#xff1a;包括docker部署方式及非docker部署方式 博客地址&#xff1a;芒果橙的个人博客 【http://mangocheng.com】 调试npm项目 1. 新增一个npm项目 2. 配置package.json及启动脚本 3. debug模式启动 远程调试docker部署的项目 1. 配置…

XMLTomcatHttp协议

XML&Tomcat&Http协议 学习目标 了解配置文件的作用了解常见的配置文件类型掌握properties文件的编写规范掌握xml文件的编写了解xml文件的约束掌握xml文件的解析掌握Tomcat的安装掌握Tomcat的使用掌握Tomcat在IDEA中的使用了解HTTP协议的发展历程了解HTTP1.0和HTTP1.1…

ConcurrentHashMap源码阅读笔记:initTable()方法

一、非常重要的sizeCtl属性 initTable()方法的作用是初始化哈希表&#xff0c;初始化哈希表就要有确定哈希表容量、创建哈希表并将哈希表的引用赋值、修改哈希表的阈值等步骤。initTable()方法里面采用了不加锁方式来确保在高并发的环境下创建哈希表的全部步骤都只能由一个线程…

Android入门第57天-使用OKHttp多线程制作像迅雷一样的断点续传功能

简介今天我们将继续使用OkHttp组件并制作一个基于多线程的可断点续传的下载器来结束Android OkHttp组件的所有知识内容。在这一课里我们会在上一次课程的基础上增加SQLite的使用以便于我们的App可以暂存下载时的实时进度&#xff0c;每次下载开始都会判断是覆盖式还是续传式下载…