SpringBoot * 的配置使用介绍
作者:刘婉晴 发布时间:2021-06-20 07:25:54
1. 配置 *
具体步骤:
编写一自定义 * 类实现接口 HandlerInterceptor
HandlerInterceptor 接口: 可在三处进行拦截——目标方法执行之前、目标方法执行完成、页面渲染以后拦截
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
将 * 注册到容器中,实现 WebMvcConfigurer 中的 addInteraptor,然后将自定义 * 注册到 * 中
指定 * 规则 —— 拦截所有 '/**'
,静态资源也会被拦截
解决静态资源同时被拦截问题:
在
addPathPatterns
中精确指定精确需要拦截资源在
excludePathPatterns
中指定排除静态资源
可在 application.properties 文件中指定静态资源统一前缀,方便排除静态资源
spring.mvc.static-path-pattern=/static/**
2. 一个小 Demo
实现未登录用户不能访问除登录页外其他页面的小Demo
1. 自定义 * 类—LoginInterceptor
自定义登录 * ,实现检测到用户未登录,则拦截用户对其他资源的访问,并返回到登录页面
package com.wanqing.admin.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Session;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/*
登录检查
*/
@Slf4j // lombok 提供的功能
public class LoginInterceptor implements HandlerInterceptor {
// 目标方法执行之前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("拦截的路径是{}", request.getRequestURI());
// 登录检查逻辑
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if(loginUser != null){
return true; // 放行
}
// 拦截住,重定向到登录页面
request.setAttribute("msg", "未登录不允许访问");
request.getRequestDispatcher("/").forward(request, response); // 转发到当前请求
return false;
}
// 目标方法执行之后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
// 页面渲染完成之后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
2. 将 * 注册到容器中
通过下列方法,将 * 注册到容器中,并配置好要拦截的路径和要放行的路径。本次 demo 中若未登录则所有路径都拦截,只放行登录页面
package com.wanqing.admin.config;
import com.wanqing.admin.interceptor.LoginInterceptor;
import lombok.extern.slf4j.Slf4j;
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 AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 在 * 的注册中心里,添加 Login *
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") //所有请求都被拦截,静态资源也被拦截
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 放行的请求
}
}
3. 原理分析
1. 根据当前请求,找到HandlerExecutionChainand,即得到可以处理请求的 Handler,以及 Handler 的所有 *
处理器执行链 :
2. 先顺序执行所有 * 的preHandle
方法
如果返回为true执行下一个 * 的
preHandle
;若为 false,直接倒叙执行所有已经执行了的 * 的
afterCompletion
方法
Step into:
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
* 方法执行 源码分析:
HandlerExecutionChain.class
—— 顺序执行所有 * 的preHandle
方法
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
—— 倒叙执行所有已经执行了的 * 的 afterCompletion
方法
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
for(int i = this.interceptorIndex; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
try {
interceptor.afterCompletion(request, response, this.handler, ex);
} catch (Throwable var7) {
logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
}
}
}
3. 如果任何一个 * 返回 false,直接跳出不执行目标方法
4. 所有 * 都返回 true,执行目标方法
5. 目标方法执行后,倒叙执行所有 * 的 postHandle 方法
6. 前面的步骤有任何异常都会直接触发 afterCompletion 方法
7. 页面成果渲染完成之后,也会倒叙触发 afterCompletion 方法
图解:
来源:https://blog.csdn.net/liuwanqing233333/article/details/127235421
猜你喜欢
- 配置宝塔面板javaweb运行环境详解,若出现404nignx错误也可按此教程进行检查1.准备:(解析成功的域名,本地运行完好的项目,宝塔面
- 摘要:介绍使用Java Stream流排序器Comparator对List集合进行多字段排序的方法,包括复杂实体对象多字段升降序排序方法。综
- * * 的概念动态拦截Actioon调用的对象,使开发者在一个Actioon执行的前后执行一段代码,也可以在Action执行前阻止其执行
- 1. 抽象类是什么️给大家上一篇小作文,看完这个,你就理解了什么叫做抽象类在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不
- 一、Java 8 基本 Base64 基本的加
- 简介:本文将帮助您使用 Spring Boot 创建简单的 REST 服务。你将学习什么是 REST 服务?如何使用 Spring Init
- java文件输出流是一种用于处理原始二进制数据的字节流类。为了将数据写入到文件中,必须将数据转换为字节,并保存到文件。package com
- 自己的一个小项目使用redis在一个类里可以注入成功,而在另一个类以却不能注入成功不多bb直接上代码package com.common.u
- 在做项目中经常会遇到有项目需求是需要判断字符为中文的一些问题,所以搜集了判断中文字符的代码片段,特此分享供大家参考。直接贴出代码了,里面有详
- handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段。使用起来很简单,就两个步骤,在主线程重写handler的handl
- 本文实例讲述了C#实现利用Windows API读写INI文件的方法。分享给大家供大家参考。具体如下:写入时,如果没有INI文件,自动创建I
- 本文实例讲述了C#检查字符串是否是合法URL地址的方法。分享给大家供大家参考。具体实现方法如下:protected string HTTPC
- 本文实例为大家分享了Unity Shader序列帧动画效果的具体代码,供大家参考,具体内容如下 实现原理主要的思想是设置显示UV
- 使用Convert接口实现类型转换器在Spring3中引入了一个Converter接口,它支持从一个Object转为另一个Object。除了
- const和readonly经常被用来修饰类的字段,两者有何异同呢?const1、声明const类型变量一定要赋初值吗?一定要赋初值publ
- 一、作用:随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问。二、随机访问文件原理: 首先把随机访问的文
- SpringTask是Spring自带的功能。实现起来比较简单。使用SpringTask实现定时任务有两种方式:1.注解方式基于注解@Sch
- 测试代码pom.xml:<?xml version="1.0" encoding="UTF-8"
- 1. 线程转储简介线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照。线程转储一般使用文本格式, 可以将其保存到文本文
- 前 言🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端☕专栏简介:深入、全面、系统的介绍消息中间件🌰 文章简介