SpringBoot Web详解静态资源规则与定制化处理
作者:鸣鼓ming 发布时间:2022-01-23 16:19:57
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");
}
}
来源:https://blog.csdn.net/qq_41865229/article/details/125354807


猜你喜欢
- 1.组装查询条件组装查询其实很简单,可以支持条件的链式编程:查询用户名包含a,年龄在 10 - 20 之间并且邮箱不为空的用户:@Testv
- BeanFactory接口:IoC容器的顶级接口,是IoC容器的最基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工
- 单例:Singleton,是指仅仅被实例化一次的类。饿汉单例设计模式一、饿汉设计模式public class SingletonHungry
- 1.@RequestMapping注解1.1@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping
- 1、CyclicBarrier:一个同步辅助类,用于协调多个子线程,让多个子线程在这个屏障前等待,直到所有子线程都到达了这个屏障时,再一起继
- 根据poi接收controller层的excel文件导入 可使用后缀
- 一.起缘故事缘于一位朋友的一道题:朋友四人玩LOL游戏。第一局,分别选择位置:中单,上单,ADC,辅助;第二局新加入的伙伴要选上单,四人可选
- 前言最近想体验下最新版本的SpringBoot,逛了下官网,发现SpringBoot目前最新版本已经是2.6.4了,版本更新确实够快的。之前
- 一 .前言某年某月某天,同事说需要一个文件排他锁功能,需求如下:(1)写操作是排他属性(2)适用于同一进程的多线程/也适用于多进程的排他操作
- 本文实例为大家分享了Java实现酒店客房管理系统的具体代码,供大家参考,具体内容如下LoginFrame.javapackage login
- 前言Android底层服务,即运行在 linux 下的进程,是 Android 系统运行的基础,完成 Android 或者说计算机最基本的功
- 目录依赖引入PowerMockito的使用使用mockito来mock实例mock对Redis的静态调用mock单例类mock私有方法Pow
- 前言如果你了解过 Liunx ,了解过 Liunx 的中管道命令 | ,那么你会发现,其实 Java 8 的 stream 和 Liunx
- 碰到一个项目,需要对指定的网页进行截图保存,晕死! 需求永远都是怪异的..... 解决是关键~ 遂写了以下代码,快准狠!(因为赶时间!) 可
- 本文实例讲述了Android编程开发之在Canvas中利用Path绘制基本图形的方法。分享给大家供大家参考,具体如下:在Android中绘制
- 1.最常用的方法是创建一个计数器,判断是否遇到‘\0',不是'\0'指针就往后加一。int my_strlen(co
- 实现的功能:默认情况下将扫描整个项目的文件可以使用@ComponentScan注解配置扫描路径只将被@Component注解修饰的类装载到容
- 本文实例讲述了C#索引属性的用法。分享给大家供大家参考。具体如下:这里演示C#类如何声明索引属性以表示不同种类事物的类似数组的集合。// i
- 前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,
- 使用new操作符来创建对象,其背后到底发生了什么?有一个父类Animal,Dog派生于Animal。class Program