一、嵌入式 Servlet 容器先决知识
1、request.getSession().getServletContext().getRealPath("/"),这个很重要,将其称为 docBase ,即"文档基目录"
2、在单模块项目中,如果不存在 src/main/webapp 目录,则 docBase 被设置为C盘下临时的随机目录,例如 C:UsersAdministratorAppDataLocalTemp omcat-docbase.2872246570823772896.8080
3、在多模块项目中,要留意 jvm 启动路径.无论该启动路径是位于父模块的路径下还是子模块的,如果 jvm 启动路径下不存在 src/main/webapp 目录,则 docBase 被设置为C 盘下临时的随机目录
综上,如果想要依照传统方式通过"文档基目录"去定位文档资源(html、css、js),则必须要确保存在 src/main/webapp 目录,即 docBase 不会被设置为随机目录.否则,建议直接通过 Springboot 配置将其定位至 classpath 下的资源(即 src/main/resource 目录下的资源),具体配置可分为 @EnableWebMvc 存在和不存在的情况
@EnableWebMvc 注解的作用就是,如果配置类上加上此注解,那么所有的 Springboot 关于 SpringMVC 的自动配置就全部失效了
二、当不存在 @EnableWebMvc 时
Springboot 的 @EnableAutoConfiguration 会启用自动配置类 WebMvcAutoConfiguration, 该类配置了一些默认的静态资源映射
1、webjars 的映射路径
webjars:以 jar 包的方式去引入静态资源(例如我们以前引入 JS 文件的时候,需要把 JS 下载下来然后拷贝到项目中,webjars 则是通过引入依赖的方式直接引入项目中所需要的 JS 等静态资源文件)
登录 webjars 官网---->http://www.webjars.org/---->选择引入资源的名称、版本、构建方式等等...---->我这里选择的是 Maven 的方式导入 webjars ---->在自己的 pom.xml 文件中引入相关的依赖就可以了
webjars 的路径映射关系源码:(/webjars/** 请求映射资源路径 /META-INF/resources/weebjars/)
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(
registry.addResourceHandler("/webjars/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod));
}
也就是如果我本地访问的路径是 http://localhost:8080/webjars/aaa/bbb.js 实际上就是访问的项目中类路径下 /META-INF/resources/webjars/aaa/bbb.js 这个资源文件
例如:引入的 webjars 结构如下:
浏览器发送请求访问 webjars 中的 jquery.js 文件
2、/** 访问当前项目的任何静态资源时,都去(静态资源的文件夹)找映射
这里的 staticPathPattern 指的就是浏览器的路径,它对应的值是 /** ,也就是访问服务器的任何资源的时候
这里的 this.resourceProperties.getStaticLocations() 对应的值如下
classpath:/META‐INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/:当前项目的根路径
具体源码如下:
所以呢我们可以得出结论 /** 映射的地址是下面 5 个文件夹内的资源
classpath:/META‐INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/:当前项目的根路径
例如我访问 localhost:8080/abc.jpg 这个路径,也就是默认的去上面 5 个默认的静态资源文件夹里面找 abc.jpg 资源
3、欢迎页:静态资源文件夹下的所有 index.html 页面,也就是访问 http://localhost:8080/ 的时候,会自动去上面的5个静态资源文件夹中找 index.html
4、看到上面 Springboot 默认的静态资源映射关系,此时,我们不需要多做什么,只要将静态资源放入上面列出的 5 个静态资源文件夹下即可通过 url 定位相关资源
5、注意:如果编写了以下的自定义配置,则 springboot 默认配置将被取消.更确切的说,一旦自定义的配置不为空,则默认配置将不被采用.(自定义的静态资源映射关系会覆盖 springboot 默认的配置,如果你还想保留 Springboot 的默认配置,那么你就需要在自定义的配置类上配置上面我们提到的 5 个默认的静态资源文件夹)
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
// 配置静态资源处理,如果启用了该配置,那么Springboot默认的静态资源路径映射将失效,
// 这里 /** 映射到下面这些路径 classpath:/resources02/、classpath:/static02/、classpath:/public02/
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/resources02/", "classpath:/static02/",
"classpath:/public02/");
}
}
6、如果不喜欢代码配置,也可采取以下属性配置方式,在 application.properties / application.yaml文件中配置
spring.resources.static-locations=classpath:/META-INF/resources02/,
classpath:/resources02/,
classpath:/static02/,
classpath:/public02/,
file:D://xiaomaomao/
三、当存在 @EnableWebMVC 时
如果使用了 @EnableWebMvc 则自动配置类 WebMvcAutoConfiguration 会失效,因此默认映射路径 /、/static、/public、META-INF/resources、/resources 都将失效
这种情况下,我们只能使用 xxxWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter 的方式来自定义配置(或者实现 WebMvcConfigurer ,其实是一个意思,因为 WebMvcConfigurerAdapter 实现了 WebMvcConfigurer 接口)
1、无前缀 ----> "文档根目录"(一般指代 src/main/webapp 目录),例如 localhost:8080/index.html 定位至 src/main/webapp/static/index.html
2、存在前缀 classpath -----> 类路径(一般指代 src/main/resources 目录)
3、存在前缀 file:// -----> 文件系统路径("绝对路径")
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/**")
// src/main/webapp/ 路径下
.addResourceLocations("resources/", "static/", "public/",
"META-INF/resources/")
// src/main/resources/ 路径下
.addResourceLocations("classpath:resources/", "classpath:static/",
"classpath:public/", "classpath:META-INF/resources/")
// 绝对路径
.addResourceLocations("file:D://xiaomaomao/");
}
}