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

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

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

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

在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

當有配置自定義HandlerInterceptor攔截器時,請求以上靜態(tài)資源路徑不會被攔截。

自定義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)資源時路徑上不用加static目錄

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

當spring boot版本升級為2.x時,訪問靜態(tài)資源就會被HandlerInterceptor攔截

當spring boot版本升級為2.x時,訪問靜態(tài)資源就會被HandlerInterceptor攔截

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

這樣對于利用HandlerInterceptor來處理訪問權(quán)限或其他相關(guān)的功能就會受影響,跟蹤源碼查看原因,是因為spring boot 2.x依賴的spring 5.x版本,相對于spring boot 1.5.x依賴的spring 4.3.x版本而言,針對資源的攔截器初始化時有區(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());
        // 此處固定添加了一個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對象,在配置類當中設(shè)置自定義的HandlerInterceptor后即可獲取到
        addInterceptors(registry);
        registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
        registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
        this.interceptors = registry.getInterceptors();
    }
    return this.interceptors.toArray();
}

從源碼當中可以看出,使用spring 5.x時,靜態(tài)資源也會執(zhí)行自定義的攔截器,因此在配置攔截器的時候需要指定排除靜態(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一樣的方式使用了。

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

總結(jié)

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

相關(guān)文章

最新評論