转载: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拦截的原因和解决方法相关推荐

  1. Spring Boot实战:静态资源处理

    前两章我们分享了Spring boot对Restful 的支持,不过Restful的接口通常仅仅返回数据.而做web开发的时候,我们往往会有很多静态资源,如html.图片.css等.那如何向前端返回静 ...

  2. 资源不足的情况怎么设置sparkrdd并行度_监控录像机资源不足或达到上限的原因及解决方法!...

    在安装网络监控摄像机过程中,很多人遇到硬盘录像机画面上提升"资源不足"或性能"达到上限"的问题,新手遇到这样的问题会选择重启录像机,但是几次反复发现并不能解决. ...

  3. 硬件特征码已达到最大上限_监控录像机“资源不足”或“达到上限” 的原因及解决方法!...

    在安装网络监控摄像机过程中,很多人遇到硬盘录像机画面上提升"资源不足"或性能"达到上限"的问题,新手遇到这样的问题会选择重启录像机,但是几次反复发现并不能解决. ...

  4. Spring Boot怎么样处理静态资源(静态资源映射规则)_Web开发

    文章目录 一.SpringBoot对静态资源的映射规则 1.所有 /webjars/**,都去 classpath:/META-INF/resources/webjars/ 找资源 2. " ...

  5. spring boot 加载静态文件

    spring boot 加载静态文件 @Slf4j @Configuration public class WebMvcConfig extends WebMvcConfigurationSuppor ...

  6. 大数据WEB阶段 Servlet配置优先级 , Spring容器设置对静态资源放行

    Servlet配置优先级 , Spring容器设置对静态资源放行 零.目录 servlet优先级 Spring容器对静态资源放行 一.servlet优先级 web.xml时整个web应用的核心配置文件 ...

  7. Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空

    Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空 一.问题描述 在Spring Boot的web ...

  8. 电脑开机提示EFI Netword 0 for ipv4 boot failed的原因及解决方法

    电脑开机提示EFI Netword 0 for ipv4 boot failed的原因及解决方法 今天上午正在我努力工作(huashui)的时候,收到了一位妹纸的求助.电脑开机提示efi networ ...

  9. 【Spring MVC】 错误: 找不到或无法加载主类 解决方法

    [Spring MVC] 错误: 找不到或无法加载主类 解决方法 最近在学习Spring,在学习SpringMVC过程中,将web.xml.Dispatcher-servlet.xml.applica ...

最新文章

  1. python连接mysql很慢 2.7_Python 2.7 学习笔记 访问mysql数据库
  2. 用 Celery 实现邮件推送系统
  3. 哪里有计算机一级的题库,计算机一级题库带答案哪有?
  4. 互动赠新书|当云原生遇到混合云:如何实现“求变”与“求稳”的平衡
  5. boost::hof::implicit用法的测试程序
  6. Perl 之 use(), require(), do(), %INC and @INC
  7. H3C 使用命令视图
  8. JavaFX官方教程(十三)之应用效果
  9. vueh5调用摄像头拍照_潜望式拍照5G手机盘点:售价相差数千元 究竟怎么选?
  10. sqoop从mysql导入hdfs_sqoop 从mysql导入数据到hdfs、hive
  11. (译)iOS Code Signing: 解惑
  12. 2021年度 Egon Balas 奖得主:达摩院印卧涛
  13. sql数据库可以创建同义词_如何使用同义词简化SQL Server数据库对象的使用
  14. linux 卸载dnw命令,linux下面安装dnw
  15. WebStrom终端使用git 出现 'git'不是内部或外部命令,也不是可运行的程序 或批处理文件
  16. 【hadoop生态之ZooKeeper】第二章Zookeeper安装【笔记+代码】
  17. SD卡提示格式化后怎么办?可尝试这种数据恢复方法快速找回!
  18. 零售商店订单数据分析
  19. C++ Awkward Digits
  20. Jackson JsonNode和ObjectNode的使用

热门文章

  1. c语言学习-判断一个数的正、负,输出相应信息
  2. uFrame近况(2016年4月8日更新)
  3. java随机数生成三位数_Java编写一程序编写一程序,实现下面功能.(1)随机产生200个三位的正整数,按每行10个数输出.(2)统计其中偶数和...
  4. OpenShift 4 Hands-on Lab (3) - 应用部署和切换策略(蓝绿、金丝雀和A/B、回滚)
  5. 解决RHEL无法访问NTFS
  6. SonarQube 8.4 发布,分析时间最多可减少 80%
  7. odoo10参考系列--测试模块
  8. matlab 散点 面,求大神指点绘制空间内散点图的包络面,,,散点程序如下
  9. 第一个程序(python)-helloworld_创建第一个python程序:‘Hello World!’
  10. c语言计算日期天数,关于计算两个日期间天数的代码,大家来看看