spring boot 2.x静态资源会被HandlerInterceptor拦截的原因和解决方法
转载:https://my.oschina.net/dengfuwei/blog/1795346
spring boot 2.x静态资源会被HandlerInterceptor拦截的原因和解决方法
在spring boot 1.5.x中,resources/static目录下的静态资源可以直接访问,并且访问路径上不用带static,比如静态资源放置位置如下图所示:
那么访问静态资源的路径可以是:
• http://localhost:8080/views/demoindex.html
• http://localhost:8080/res/js/jquery.min.js
当有配置自定义HandlerInterceptor拦截器时,请求以上静态资源路径不会被拦截。自定义HandlerInterceptor拦截器源码如下:
package com.itopener.demo.config;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
* @author fuwei.deng
* @date 2018年4月13日 下午3:32:26
* @version 1.0.0
*/
public class LoginRequiredInterceptor extends HandlerInterceptorAdapter {
private final Logger logger = LoggerFactory.getLogger(LoginRequiredInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info(request.getRequestURI());
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info(request.getRequestURI());
super.afterCompletion(request, response, handler, ex);
}
}
配置如下:
package com.itopener.demo.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @author fuwei.deng
* @date 2018年4月13日 下午3:32:54
* @version 1.0.0
*/
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class);
@Override
public void addInterceptors(InterceptorRegistry registry) {
logger.info("add interceptors");
registry.addInterceptor(new LoginRequiredInterceptor());
}
}
访问静态资源时路径上不用加static目录:
当spring boot版本升级为2.x时,访问静态资源就会被HandlerInterceptor拦截
这样对于利用HandlerInterceptor来处理访问权限或其他相关的功能就会受影响,跟踪源码查看原因,是因为spring boot 2.x依赖的spring 5.x版本,相对于spring boot 1.5.x依赖的spring 4.3.x版本而言,针对资源的拦截器初始化时有区别,具体源码在WebMvcConfigurationSupport中,spring 4.3.x源码如下:
/**
* Return a handler mapping ordered at Integer.MAX_VALUE-1 with mapped
* resource handlers. To configure resource handling, override
* {@link #addResourceHandlers}.
*/
@Bean
public HandlerMapping resourceHandlerMapping() {
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
this.servletContext, mvcContentNegotiationManager());
addResourceHandlers(registry);
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
if (handlerMapping != null) {
handlerMapping.setPathMatcher(mvcPathMatcher());
handlerMapping.setUrlPathHelper(mvcUrlPathHelper());
// 此处固定添加了一个Interceptor
handlerMapping.setInterceptors(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
handlerMapping.setCorsConfigurations(getCorsConfigurations());
}
else {
handlerMapping = new EmptyHandlerMapping();
}
return handlerMapping;
}
而spring 5.x的源码如下:
/**
* Return a handler mapping ordered at Integer.MAX_VALUE-1 with mapped
* resource handlers. To configure resource handling, override
* {@link #addResourceHandlers}.
*/
@Bean
public HandlerMapping resourceHandlerMapping() {
Assert.state(this.applicationContext != null, "No ApplicationContext set");
Assert.state(this.servletContext != null, "No ServletContext set");
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
this.servletContext, mvcContentNegotiationManager(), mvcUrlPathHelper());
addResourceHandlers(registry);
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
if (handlerMapping != null) {
handlerMapping.setPathMatcher(mvcPathMatcher());
handlerMapping.setUrlPathHelper(mvcUrlPathHelper());
// 此处是将所有的HandlerInterceptor都添加了(包含自定义的HandlerInterceptor)
handlerMapping.setInterceptors(getInterceptors());
handlerMapping.setCorsConfigurations(getCorsConfigurations());
}
else {
handlerMapping = new EmptyHandlerMapping();
}
return handlerMapping;
}
/**
* Provide access to the shared handler interceptors used to configure
* {@link HandlerMapping} instances with. This method cannot be overridden,
* use {@link #addInterceptors(InterceptorRegistry)} instead.
*/
protected final Object[] getInterceptors() {
if (this.interceptors == null) {
InterceptorRegistry registry = new InterceptorRegistry();
// 此处传入新new的registry对象,在配置类当中设置自定义的HandlerInterceptor后即可获取到
addInterceptors(registry);
registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
this.interceptors = registry.getInterceptors();
}
return this.interceptors.toArray();
}
从源码当中可以看出,使用spring 5.x时,静态资源也会执行自定义的拦截器,因此在配置拦截器的时候需要指定排除静态资源的访问路径,即配置改为如下即可:
package com.itopener.demo.config;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author fuwei.deng
* @date 2018年4月13日 下午3:32:54
* @version 1.0.0
*/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
private final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class);
@Override
public void addInterceptors(InterceptorRegistry registry) {
logger.info("add interceptors");
registry.addInterceptor(new LoginRequiredInterceptor()).excludePathPatterns(Arrays.asList("/views/**", "/res/**"));
}
}
这样就可以和spring boot 1.5.x一样的方式使用了。不过从源码当中可以看出,每个静态资源的请求都会被自定义Interceptor拦截,只是通过访问路径判断后不会执行拦截器的内容,所以spring 5.x相对于spring 4.3.x而言,这部分处理的性能会更低一些
说明:
• 本文中测试使用的具体版本:
• spring-boot-1.5.3.RELEASE(相对应的spring版本是spring-webmvc-4.3.8.RELEASE)
• spring-boot-2.0.1.RELEASE(相对应的spring版本是spring-webmvc-5.0.5.RELEASE)
• 关于配置类,在spring boot 2.x已经改为最低支持jdk8版本,而jdk8中的接口允许有默认实现,所以已经废弃掉WebMvcConfigurerAdapter适配类,而改为直接实现WebMvcConfigurer接口
g boot 2.x静态资源会被HandlerInterceptor拦截的原因和解决方法
spring boot 2.x静态资源会被HandlerInterceptor拦截的原因和解决方法相关推荐
- Spring Boot实战:静态资源处理
前两章我们分享了Spring boot对Restful 的支持,不过Restful的接口通常仅仅返回数据.而做web开发的时候,我们往往会有很多静态资源,如html.图片.css等.那如何向前端返回静 ...
- 资源不足的情况怎么设置sparkrdd并行度_监控录像机资源不足或达到上限的原因及解决方法!...
在安装网络监控摄像机过程中,很多人遇到硬盘录像机画面上提升"资源不足"或性能"达到上限"的问题,新手遇到这样的问题会选择重启录像机,但是几次反复发现并不能解决. ...
- 硬件特征码已达到最大上限_监控录像机“资源不足”或“达到上限” 的原因及解决方法!...
在安装网络监控摄像机过程中,很多人遇到硬盘录像机画面上提升"资源不足"或性能"达到上限"的问题,新手遇到这样的问题会选择重启录像机,但是几次反复发现并不能解决. ...
- Spring Boot怎么样处理静态资源(静态资源映射规则)_Web开发
文章目录 一.SpringBoot对静态资源的映射规则 1.所有 /webjars/**,都去 classpath:/META-INF/resources/webjars/ 找资源 2. " ...
- spring boot 加载静态文件
spring boot 加载静态文件 @Slf4j @Configuration public class WebMvcConfig extends WebMvcConfigurationSuppor ...
- 大数据WEB阶段 Servlet配置优先级 , Spring容器设置对静态资源放行
Servlet配置优先级 , Spring容器设置对静态资源放行 零.目录 servlet优先级 Spring容器对静态资源放行 一.servlet优先级 web.xml时整个web应用的核心配置文件 ...
- Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空
Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空 一.问题描述 在Spring Boot的web ...
- 电脑开机提示EFI Netword 0 for ipv4 boot failed的原因及解决方法
电脑开机提示EFI Netword 0 for ipv4 boot failed的原因及解决方法 今天上午正在我努力工作(huashui)的时候,收到了一位妹纸的求助.电脑开机提示efi networ ...
- 【Spring MVC】 错误: 找不到或无法加载主类 解决方法
[Spring MVC] 错误: 找不到或无法加载主类 解决方法 最近在学习Spring,在学习SpringMVC过程中,将web.xml.Dispatcher-servlet.xml.applica ...
最新文章
- python连接mysql很慢 2.7_Python 2.7 学习笔记 访问mysql数据库
- 用 Celery 实现邮件推送系统
- 哪里有计算机一级的题库,计算机一级题库带答案哪有?
- 互动赠新书|当云原生遇到混合云:如何实现“求变”与“求稳”的平衡
- boost::hof::implicit用法的测试程序
- Perl 之 use(), require(), do(), %INC and @INC
- H3C 使用命令视图
- JavaFX官方教程(十三)之应用效果
- vueh5调用摄像头拍照_潜望式拍照5G手机盘点:售价相差数千元 究竟怎么选?
- sqoop从mysql导入hdfs_sqoop 从mysql导入数据到hdfs、hive
- (译)iOS Code Signing: 解惑
- 2021年度 Egon Balas 奖得主:达摩院印卧涛
- sql数据库可以创建同义词_如何使用同义词简化SQL Server数据库对象的使用
- linux 卸载dnw命令,linux下面安装dnw
- WebStrom终端使用git 出现 'git'不是内部或外部命令,也不是可运行的程序 或批处理文件
- 【hadoop生态之ZooKeeper】第二章Zookeeper安装【笔记+代码】
- SD卡提示格式化后怎么办?可尝试这种数据恢复方法快速找回!
- 零售商店订单数据分析
- C++ Awkward Digits
- Jackson JsonNode和ObjectNode的使用
热门文章
- c语言学习-判断一个数的正、负,输出相应信息
- uFrame近况(2016年4月8日更新)
- java随机数生成三位数_Java编写一程序编写一程序,实现下面功能.(1)随机产生200个三位的正整数,按每行10个数输出.(2)统计其中偶数和...
- OpenShift 4 Hands-on Lab (3) - 应用部署和切换策略(蓝绿、金丝雀和A/B、回滚)
- 解决RHEL无法访问NTFS
- SonarQube 8.4 发布,分析时间最多可减少 80%
- odoo10参考系列--测试模块
- matlab 散点 面,求大神指点绘制空间内散点图的包络面,,,散点程序如下
- 第一个程序(python)-helloworld_创建第一个python程序:‘Hello World!’
- c语言计算日期天数,关于计算两个日期间天数的代码,大家来看看