SpringBoot Web详解静态资源规则与定制化处理
作者:鸣鼓ming
1.相关概念
- Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。
- 建议使用Spring Boot的默认配置方式,如果需要特殊处理的再通过配置文件进行修改。
- 如果想要自己完全控制WebMVC,就需要在@Configuration注解的配置类上增加@EnableWebMvc, 增加该注解以后WebMvcAutoConfiguration中配置就不会生效,你需要自己来配置需要的每一项(可以使用继承)。
2.静态资源目录
默认只要静态资源放在类路径(resources)下:
/static
/public
/resources
/META-INF/resources
浏览器访问: 当前项目根路径/ + 静态资源名
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面。
我们在controller里写个测试方法来测试一下
把controller里的方法注释后
也可以改变默认的静态资源路径,/static,/public,/resources, /META-INF/resources失效
application.properties
#静态资源路径
spring.resources.static-locations=classpath:/dir1/,classpath:/dir2/
3.静态资源访问前缀
application.properties
#静态资源访问前缀, 就是浏览器网址路径加前缀
spring.mvc.static-path-pattern=/res/**
4.欢迎页支持
就是网址上没有访问映射时, 会自动跳转到欢迎页,
静态资源路径下 index.html。
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
5.自定义favicon
指网页标签上的小图标。
favicon.ico 放在静态资源目录下即可。
6.源码分析
- SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)
- SpringMVC功能的自动配置类WebMvcAutoConfiguration生效
@AutoConfiguration( after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class} ) @ConditionalOnWebApplication( type = Type.SERVLET ) @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) @AutoConfigureOrder(-2147483638) public class WebMvcAutoConfiguration { public static final String DEFAULT_PREFIX = ""; public static final String DEFAULT_SUFFIX = ""; public static final PathPatternParser pathPatternParser = new PathPatternParser(); private static final String SERVLET_LOCATION = "/"; public WebMvcAutoConfiguration() { }
给容器中配置的内容:
配置文件的相关属性的绑定:WebMvcProperties == spring.mvc、WebProperties==spring.web
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware { private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class); private final Resources resourceProperties; private final WebMvcProperties mvcProperties; private final ListableBeanFactory beanFactory; private final ObjectProvider<HttpMessageConverters> messageConvertersProvider; private final ObjectProvider<DispatcherServletPath> dispatcherServletPath; private final ObjectProvider<ServletRegistrationBean<?>> servletRegistrations; private final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer; private ServletContext servletContext;
配置类只有一个有参构造器
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) { this.resourceProperties = webProperties.getResources(); this.mvcProperties = mvcProperties; this.beanFactory = beanFactory; this.messageConvertersProvider = messageConvertersProvider; this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); this.dispatcherServletPath = dispatcherServletPath; this.servletRegistrations = servletRegistrations; this.mvcProperties.checkConfiguration(); }
- ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
- WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
- ListableBeanFactory beanFactory Spring的beanFactory
- HttpMessageConverters 找到所有的HttpMessageConverters
- ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。
- DispatcherServletPath
- ServletRegistrationBean 给应用注册Servlet、Filter…
资源处理的默认规则
public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/"); this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (this.servletContext != null) { ServletContextResource resource = new ServletContextResource(this.servletContext, "/"); registration.addResourceLocations(new Resource[]{resource}); } }); } }
根据上述代码,我们可以同过配置禁止所有静态资源规则。
application.properties
#禁用所有静态资源规则
spring.web.resources.add-mappings=false
静态资源处理规则:
public static class Resources { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}; private String[] staticLocations; private boolean addMappings; private boolean customized; private final WebProperties.Resources.Chain chain; private final WebProperties.Resources.Cache cache;
欢迎页处理规则:
@Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern()); welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider)); welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations()); return welcomePageHandlerMapping; }
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { if (welcomePage != null && "/**".equals(staticPathPattern)) { logger.info("Adding welcome page: " + welcomePage); this.setRootViewName("forward:index.html"); } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { logger.info("Adding welcome page template: index"); this.setRootViewName("index"); } }
到此这篇关于SpringBoot Web详解静态资源规则与定制化处理的文章就介绍到这了,更多相关SpringBoot静态资源规则与定制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!