欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring?boot?2.x靜態(tài)資源會(huì)被攔截器攔截的原因分析及解決

 更新時(shí)間:2023年01月12日 09:22:40   作者:某某  
這篇文章主要介紹了spring?boot?2.x靜態(tài)資源會(huì)被攔截器攔截的原因分析及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spring boot 2.x靜態(tài)資源會(huì)被攔截器攔截的原因

在spring boot 1.5.x中,resources/static目錄下的靜態(tài)資源可以直接訪問,并且訪問路徑上不用帶static,比如靜態(tài)資源放置位置如下圖所示:

靜態(tài)資源目錄結(jié)構(gòu)

那么訪問靜態(tài)資源的路徑可以是:

http://localhost:8080/views/demoindex.html

http://localhost:8080/res/js/jquery.min.js

當(dāng)有配置自定義HandlerInterceptor攔截器時(shí),請(qǐng)求以上靜態(tài)資源路徑不會(huì)被攔截。

自定義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());
	}
 
}

訪問靜態(tài)資源時(shí)路徑上不用加static目錄

spring boot 1.5.x訪問靜態(tài)資源

當(dāng)spring boot版本升級(jí)為2.x時(shí),訪問靜態(tài)資源就會(huì)被HandlerInterceptor攔截

當(dāng)spring boot版本升級(jí)為2.x時(shí),訪問靜態(tài)資源就會(huì)被HandlerInterceptor攔截

HandlerInterceptor攔截靜態(tài)資源日志

這樣對(duì)于利用HandlerInterceptor來處理訪問權(quán)限或其他相關(guān)的功能就會(huì)受影響,跟蹤源碼查看原因,是因?yàn)閟pring boot 2.x依賴的spring 5.x版本,相對(duì)于spring boot 1.5.x依賴的spring 4.3.x版本而言,針對(duì)資源的攔截器初始化時(shí)有區(qū)別

具體源碼在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());
        // 此處固定添加了一個(gè)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對(duì)象,在配置類當(dāng)中設(shè)置自定義的HandlerInterceptor后即可獲取到
        addInterceptors(registry);
        registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
        registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
        this.interceptors = registry.getInterceptors();
    }
    return this.interceptors.toArray();
}

從源碼當(dāng)中可以看出,使用spring 5.x時(shí),靜態(tài)資源也會(huì)執(zhí)行自定義的攔截器,因此在配置攔截器的時(shí)候需要指定排除靜態(tài)資源的訪問路徑,即配置改為如下即可:

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一樣的方式使用了。

不過從源碼當(dāng)中可以看出,每個(gè)靜態(tài)資源的請(qǐng)求都會(huì)被自定義Interceptor攔截,只是通過訪問路徑判斷后不會(huì)執(zhí)行攔截器的內(nèi)容,所以spring 5.x相對(duì)于spring 4.3.x而言,這部分處理的性能會(huì)更低一些

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論