浅谈Springboot实现 * 的两种方式
作者:怪咖软妹@ 发布时间:2023-05-10 05:53:50
实现过滤请求有两种方式:
一种就是用 * ,一种就是过滤器
* 相对来说比较专业,而过滤器虽然不专业但是也能完成基本的拦截请求要求。
一、 * 方式
1、配置HandlerInterceptor
下面这个也是我们公司项目 * 的写法,总体来说感觉还不错,我就记录了下来。
利用了一个静态Pattern变量存储不走 * 的路径,然后在preHandle方法当中进行过滤,让他返回true。
@Component
public class LoginInterceptor implements HandlerInterceptor{
private static final Pattern SHOULD_NOT_FILTER_URL_PATTERN;
static {
List<String> urlList = new ArrayList<>();
// 将不走 * 的请求存放到Pattern
urlList.add("(socket/.*)");
urlList.add("(user/findUserList)");
StringBuilder sb = new StringBuilder();
for (String url : urlList) {
sb.append(url);
sb.append("|");
}
sb.setLength(sb.length() - 1);
SHOULD_NOT_FILTER_URL_PATTERN = Pattern.compile(sb.toString());
}
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
// 获取访问的url
String servletPath = request.getServletPath();
// 排除特定请求
if (SHOULD_NOT_FILTER_URL_PATTERN.matcher(servletPath).find()) {
return true;
}
if (session.getAttribute("user") != null) {
// 可能有的项目在校验完session,还会校验token
String token = request.getHeader("access_token");
// 此处业务省略。。。
return true;
}
return false;
}
/**
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}
2、注册 *
配置完上面的 * 还需要注册 * 。
WebMvcConfigurerAdapter类是 Spring内部的一种配置方式
采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个 * 组成一个 * 链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
3、使用 * 的坑
继承WebMvcConfigurerAdapter 重写addInterceptors方法的时候,一定要使用注入方式,将loginInterceptor注入到变量当中,要么就使用@Bean注解的方式,将loginInterceptor( * )注入到容器。
之所以这么搞是因为 * 在 Bean 初始化之前进行,所以在 * 中无法像这样注入 Bean。
就算加了@Component,他是存放于容器当中了,但是他存放容器当中的对象属性,是空属性。
在WebMvcConfigurerAdapter 使用@Autowired注入了一遍 * ,属性就有值了。
说白了不管采用哪种方案,目的只有一个,让对象的属性有值,因为 * 比其他对象初始化早,导致属性为空,想让他有值,就想办法让他重新走一遍spring注入容器,也可以采用这种方式:
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
// 这么写的目的是为了在SessionInterceptor中能注入spring中的service
@Bean
LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个 * 组成一个 * 链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(loginInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
二、过滤器方式
本人这一篇博客写了关于filter的一些知识:https://www.jb51.net/article/204084.htm
1、实现Filter接口
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Component;
@Component
@WebFilter(filterName = "requestParamFilter",urlPatterns = "/*")
public class RequestParamFilter implements Filter {
private static final Pattern SHOULD_NOT_FILTER_URL_PATTERN;
static {
List<String> urlList = new ArrayList<>();
// 将不走 * 的请求存放到Pattern
urlList.add("(socket/.*)");
urlList.add("(user/findUserList)");
StringBuilder sb = new StringBuilder();
for (String url : urlList) {
sb.append(url);
sb.append("|");
}
sb.setLength(sb.length() - 1);
SHOULD_NOT_FILTER_URL_PATTERN = Pattern.compile(sb.toString());
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
// 发送请求会执行这个方法
// 一个doFilter相当于 * 的执行前和执行后
// filterChain.doFilter后面的内容就是执行后的内容,假如不执行filterChain.doFilter方法相当于方法被拦截
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("sunhan---请求参数过滤器!---test1");
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpSession session = request.getSession();
// 获取访问的url
String servletPath = request.getServletPath();
// 排除特定请求
if (SHOULD_NOT_FILTER_URL_PATTERN.matcher(servletPath).find()) {
filterChain.doFilter(servletRequest,servletResponse);
}
System.out.println("开始拦截了................");
//业务代码
}
@Override
public void destroy() {
}
}
2、使用过滤器需要注意的
* 可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在 * 里注入一个service,可以调用业务逻辑
执行顺序如下:
来源:https://blog.csdn.net/weixin_43888891/article/details/119778754


猜你喜欢
- Spring Security 基本介绍这里就不对Spring Security进行过多的介绍了,具体的可以参考官方文档我就只说下Sprin
- 在Java中,线程有5中不同状态,分别是:新建(New)、就绪(Runable)、运行(Running)、阻塞(Blocked)和死亡(De
- UGUI的滑动组件虽然表现上和NGUI的ScrollView一致,但是它更美好的是开放源码的,不了解原理的时候直接查源码就OK。在使用Scr
- 前言传统的Restful API 存在诸多的问题,首先它无法控制返回的字段,前端也无法预判后端的返回结果,另外不同的返回结果对应不同的请求地
- 本文实例为大家分享了C#重写DataGridView的实例代码,供大家参考,具体内容如下using System;using S
- Android里判断是否可以上网,常用的是如下方法:/** * 检测网络是否连接 * * @return */private boolea
- 简介Spring Security是一个基于Spring框架的安全认证和授权框架,它提供了一套全面的安全解决方案,可以在Web应用、移动应用
- 我们在实际开发中,有的时候需要储存或者备份比较复杂的数据。这些数据的特点是,内容多、结构大,比如短信备份等。我们知道SharedPrefer
- 1.算法效率算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。时间复杂度主要衡
- 初学Android编程,Android SDK中提供的Sample代码自然是最好的学习材料。 
- 1、应用场景:从一份html文件中或从String(是html内容)中提取纯文本,去掉网页标签;2、代码一:replaceAll搞定//从h
- 本文实例为大家分享了Flutter Drawer抽屉菜单示例代码,供大家参考,具体内容如下一.Flutter Drawer组件简介1.源码查
- 异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题。1
- ThreadLocal类,代表一个线程局部变量,通过把数据放在ThreadLocal中,可以让每个线程创建一个该变量的副本。也可以看成是线程
- 前言事务对java开发的同学来说并不陌生,我们使用事务的目的在于避免产生重复数据或者说利用数据存储中间件的事务特性确保数据的精准性,比如大家
- JSTL条件行为和遍历行为JSTL的条件行为标签有四个:if,choose,when,otherwise标签1、if标签是对某一个条件进行测
- 一、MyBatisPlusConfig中配置分页插件/** * 配置分页插件 * @
- 官方文档:https://central.sonatype.org/publish/publish-maven/#a-complete-ex
- 这篇文章主要介绍了Java如何利用return结束方法调用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- MyBatis注解实现动态SQL在 Mybatis 中,使用注解可以很方便的进行sql操作,但很多动态 SQL 都是由 xml 配置实现的。