springboot webflux 靜態資源映射
************************
相關類與接口
ResourceProperties
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
//默認 /META-INF/resources、/resources、/static、/public下的文件可以直接訪問
private String[] staticLocations;
private boolean addMappings;
private final ResourceProperties.Chain chain;
private final ResourceProperties.Cache cache;
public ResourceProperties() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.chain = new ResourceProperties.Chain();
this.cache = new ResourceProperties.Cache();
}
WebFluxProperties
@ConfigurationProperties(
prefix = "spring.webflux"
)
public class WebFluxProperties {
private String basePath;
private final WebFluxProperties.Format format = new WebFluxProperties.Format();
private String staticPathPattern = "/**"; //靜態資源訪問前綴,默認爲:/**
public WebFluxProperties() {
}
WebFluxAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnWebApplication(
type = Type.REACTIVE
)
@ConditionalOnClass({WebFluxConfigurer.class})
@ConditionalOnMissingBean({WebFluxConfigurationSupport.class})
@AutoConfigureAfter({ReactiveWebServerFactoryAutoConfiguration.class, CodecsAutoConfiguration.class, ValidationAutoConfiguration.class})
@AutoConfigureOrder(-2147483638)
public class WebFluxAutoConfiguration {
public WebFluxAutoConfiguration() {
}
****************
內部類:WebFluxAutoConfiguration.WebFluxConfig
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({ResourceProperties.class, WebFluxProperties.class})
@Import({WebFluxAutoConfiguration.EnableWebFluxConfiguration.class})
public static class WebFluxConfig implements WebFluxConfigurer {
private static final Log logger = LogFactory.getLog(WebFluxAutoConfiguration.WebFluxConfig.class);
private final ResourceProperties resourceProperties;
private final WebFluxProperties webFluxProperties;
private final ListableBeanFactory beanFactory;
private final ObjectProvider<HandlerMethodArgumentResolver> argumentResolvers;
private final ObjectProvider<CodecCustomizer> codecCustomizers;
private final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
private final ObjectProvider<ViewResolver> viewResolvers;
public WebFluxConfig(ResourceProperties resourceProperties, WebFluxProperties webFluxProperties, ListableBeanFactory beanFactory, ObjectProvider<HandlerMethodArgumentResolver> resolvers, ObjectProvider<CodecCustomizer> codecCustomizers, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizer, ObjectProvider<ViewResolver> viewResolvers) {
this.resourceProperties = resourceProperties;
this.webFluxProperties = webFluxProperties;
this.beanFactory = beanFactory;
this.argumentResolvers = resolvers;
this.codecCustomizers = codecCustomizers;
this.resourceHandlerRegistrationCustomizer = (ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizer.getIfAvailable();
this.viewResolvers = viewResolvers;
}
public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
this.argumentResolvers.orderedStream().forEach((xva$0) -> {
configurer.addCustomResolver(new HandlerMethodArgumentResolver[]{xva$0});
});
}
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
this.codecCustomizers.orderedStream().forEach((customizer) -> {
customizer.customize(configurer);
});
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
if (!registry.hasMappingForPattern("/webjars/**")) {
ResourceHandlerRegistration registration = registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"});
this.configureResourceCaching(registration);
this.customizeResourceHandlerRegistration(registration);
}
String staticPathPattern = this.webFluxProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
ResourceHandlerRegistration registration = registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(this.resourceProperties.getStaticLocations());
//配置靜態資源映射,設置前綴staticPathPattern:this.webFluxProperties.getStaticPathPattern()
//靜態資源路徑:this.resourceProperties.getStaticLocations()
this.configureResourceCaching(registration);
this.customizeResourceHandlerRegistration(registration);
}
}
}
private void configureResourceCaching(ResourceHandlerRegistration registration) {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
Cachecontrol cacheControl = this.resourceProperties.getCache().getCachecontrol();
if (cachePeriod != null && cacheControl.getMaxAge() == null) {
cacheControl.setMaxAge(cachePeriod);
}
registration.setCacheControl(cacheControl.toHttpCacheControl());
}
public void configureViewResolvers(ViewResolverRegistry registry) {
this.viewResolvers.orderedStream().forEach(registry::viewResolver);
}
public void addFormatters(FormatterRegistry registry) {
ApplicationConversionService.addBeans(registry, this.beanFactory);
}
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) {
if (this.resourceHandlerRegistrationCustomizer != null) {
this.resourceHandlerRegistrationCustomizer.customize(registration);
}
}
}
************************
示例
****************
靜態文件:hello.html
hello.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div align="center" style="color: purple">
hello world
</div>
</body>
</html>
****************
配置文件
application.yml:默認配置
spring:
webflux:
static-path-pattern: /**
localhost:8080/hello.html,輸出:hello world
****************
配置文件
application.yml
spring:
webflux:
static-path-pattern: /resources/**
localhost:8080/resources/hello.html,輸出:hello world