这章来讲解一下web开发中一些简单的功能,并对其进行分析
静态资源访问
1、静态资源访问目录
先来看一下官方文档,他说Springboot的静态访问目录默认有4个,/static ,/public,/resources,/META-INF/resources,比如我在这其中的一个目录下放一个文件,只需要访问localhost:port/xxx即可访问
By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources ) in the classpath or from the root of the ServletContext . It uses the ResourceHttpRequestHandler from Spring MVC so that you can modify that behavior by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.
2、静态资源访问前缀
上面也说到SpringBoot默认是没有静态资源的访问前缀的,在开发过程中用到过滤器我们不希望扫描到静态资源,那么就可以为这些静态资源加上访问前缀,只需要设置spring.mvc.static-path-pattern 即可
By default, resources are mapped on /** , but you can tune that with the spring.mvc.static-path-pattern property. For instance, relocating all resources to /resources/** can be achieved as follows
spring:
mvc:
static-path-pattern: /res/**
3、修改静态资源路径
SpringBoot支持我们自定义静态资源路径,需要注意的是,是使用我们配置的目录来代替默认路径,所以如果我们配置了静态资源路径,默认的会失效
ou can also customize the static resource locations by using the spring.web.resources.static-locations property (replacing the default values with a list of directory locations). The root Servlet context path, "/" , is automatically added as a location as well.
spring:
web:
resources:
static-locations: [classpath:/haha/]
4、webjar的访问
webjar是一个整合了静态资源的jar包,webjar官网
我们可以通过导入依赖的方式引入静态资源,如:js,jQuery等
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
In addition to the “standard” static resource locations mentioned earlier, a special case is made for Webjars content. Any resources with a path in /webjars/** are served from jar files if they are packaged in the Webjars format.
导入依赖之后我们可以通过访问 localhost:port/webjars/xxx来访问该路径下的静态资源
欢迎页
SpringBoot只需要你在静态资源目录下放一个index.html文件,他就会识别他为欢迎页,就是说访问localhost:port可以直接跳蛛拿到此页面,如果没有这个文件的话,他还会查找发送的请求返回值有没有返回index模板的,如果有也会被识别为欢迎页
特别需要注意的是,设置了静态资源访问前缀会使这个功能失效
Spring Boot supports both static and templated welcome pages. It first looks for an index.html file in the configured static content locations. If one is not found, it then looks for an index template. If either is found, it is automatically used as the welcome page of the application.
自定义Favicon
这个是比较有意思的小玩意,就是访问网站是他的icon,我们可以在静态文件目录下创建一个Favicon.ico图片文件,就会被自动识别为当前网站的icon,小黄就拿了bilibili的icon做了一个实验
源码分析
以上的内容都涉及到自动配置,所有涉及到自动配置肯定都在xxxxAutoConfiguration配置类中
所有涉及到SpringMvc的配置,都在WebMvcAutoConfiguration类下来定义
看这个类是否自动配置,首先得看@Conditional条件配置是否都满足,
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
来看一下这个类中配置了什么东西
像Rest风格的请求过滤器等,就不在这里贴出来了,我们主要是来找一下关于静态资源的配置
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({WebProperties.class})
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
public EnableWebMvcConfiguration(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, WebProperties webProperties, ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ListableBeanFactory beanFactory) {
this.resourceProperties = (Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());
this.mvcProperties = mvcProperties;
this.webProperties = webProperties;
this.mvcRegistrations = (WebMvcRegistrations)mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
}
这个类中有且只有一个有参构造器,那么构造器中所有参数的值都会从容器中确定
ResourceProperties===绑定前缀为spring.resources的配置文件
WebMvcProperties===绑定前缀spring.mvc的配置文件
下面这段代码就是加载默认静态资源路径,
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});
}
});
}
}
这里设置了默认地址
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;
欢迎页设置
@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");
}
}
|