13-SpringBoot进行Web开发
我们创建一个d-springboot-web模块,所有的例子都在这个模块着实现
1、静态资源读取探究
这里我们需要知道springboot可以从什么位置读取静态资源。
首先关于静态资源的配置是在WebMvcAutoConfiguration这个自动配置类中配置的,我们首先打开该类。
然后找到其中的一个静态内部类:WebMvcAutoConfigurationAdapter,是一个适配类,部分源码如下,可以看到这个类和三个属性配置类绑定了:WebMvcProperties.class, ResourceProperties.class, WebProperties.class
@Configuration(
proxyBeanMethods = false
)
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
......
......
......
}
我们可以看到该类上面的@Import注解中导入了一个组件:WebMvcAutoConfiguration.EnableWebMvcConfiguration.class
这个EnableWebMvcConfiguration类中有一个方法:addResourceHandlers,添加资源处理器,其中就定义了默认静态资源的读取位置,如下
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
ServletContext servletContext = this.getServletContext();
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
}
});
}
}
-
首先我们分析第一个if
什么意思呢?
首先解释如何在配置文件中自定义要静态资源的加载目录,具体写法如下
#表示该项目加载静态资源只会到根目录下的hello目录或者是study目录下加载 spring.mvc.static-path-pattern=/hello/,classpath:/study/
解释如果注册了webjars就到classpath:/META-INF/resources/webjars/这个目录下加载静态资源
什么事webjars?
直接百度webjars,进入官网
可以看到这些都是前端框架的jar包,我们直接复制一个jquery的maven坐标,然后粘贴到pom文件中
解释/webjars/**
上面的webjars就代表了locations属性的classpath:/META-INF/resources/webjars/,代表三级目录
所以我们的URL可以这样写就可以访问静态:http://localhost:8080/webjars/jquery/3.6.0/jquery.js
-
分析第二个if
第二个if表示添加了一个当前上下文的资源处理器,目录是一个/,表示的是根目录下的静态资源都可以加载
我们还可以寻找更多关于静态资源加载的配置,我们找到WebProperties这个类,可以看到其中一个静态内部类Resources有一个数组属性,源码如下
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; public Resources() { this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS; this.addMappings = true; this.customized = false; this.chain = new WebProperties.Resources.Chain(); this.cache = new WebProperties.Resources.Cache(); } public String[] getStaticLocations() { return this.staticLocations; } public void setStaticLocations(String[] staticLocations) { this.staticLocations = this.appendSlashIfNecessary(staticLocations); this.customized = true; } ...
可以看到我们还可以将静态资源存放在"classpath:/resources/", "classpath:/static/", "classpath:/public/"这三个目录下,
经过测试,这三个目录的优先级是resources最高,static第二,public最低。
一般我们存放静态资源都是这三个目录,使用最多的是static
2、首页跳转和项目网页图标设置
-
首页跳转设置
这我们探究springboot的web项目欢迎页面的设置。
首先我们打开WebMvcAutoConfiguration这个自动配置类
找到一个方法:welcomePageHandlerMapping,源码如下
@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 welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
其中参数中执行了一个getWelcomPage方法以及获取静态路径的方法
我们先分析getWelcomPage方法,源码如下
private Resource getWelcomePage() { String[] var1 = this.resourceProperties.getStaticLocations(); int var2 = var1.length; for(int var3 = 0; var3 < var2; ++var3) { String location = var1[var3]; Resource indexHtml = this.getIndexHtml(location); if (indexHtml != null) { return indexHtml; } } ServletContext servletContext = this.getServletContext(); if (servletContext != null) { return this.getIndexHtml((Resource)(new ServletContextResource(servletContext, "/"))); } else { return null; } }
该方法中的this.resourceProperties.getStaticLocations();获取的是ResourcesProperties中内部类Resources的staticLocations数组的值,该数组内容是:{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}。所以会从这四个路径中加载欢迎页面。
而其中的this.getIndexHtml(location); 方法源码是
private Resource getIndexHtml(Resource location) { try { Resource resource = location.createRelative("index.html"); if (resource.exists() && resource.getURL() != null) { return resource; } } catch (Exception var3) { } return null; }
从源码可以看出,springboot会加载存放在上面四个路径目录下的欢迎页面名称是"index.html"
所以我们只需要将欢迎页面命名为index.html然后存放在上面四个路径其中之一就可以了。
我们再分析另一个参数方法this.mvcProperties.getStaticPathPattern(),这里经过测试,知道获取的是静态资源路径,即ResourcesProperties中的staticPathPattern参数,这个参数可以在配置文件中修改
#表示该项目加载静态资源只会到根目录下的hello目录或者是study目录下加载 spring.mvc.static-path-pattern=/hello/,classpath:/study/
这样就可以让springboot项目加载自定义路径中的欢迎页面
一般情况下我们会把欢迎页面放到templates这个模板目录中,这个目录中的资源是无法直接通过URL访问的,需要项目内部跳转。所以我们可以创建一个欢迎页面的controller类,在其中编写跳转页面。
-
网页图标设置
首先我们将想要的图片重命名为favicon.ico的格式,然后存放在静态资源加载目录下,然后在配置文件中修改不实用默认图标,就可以在我们访问这个项目的网页上显示图标了。如下
spring.mvc.favicon.enabled=false
这种方式只能在springboot2.1版本之前使用