由于高版本
的Maven-Eclipse插件
,IDE在项目编译的时候
会默认将src/main/resources
下的静态资源排除(Exluded)
,导致程序执行的时候,找不到静态资源,报告错误如下:
java.io.FileNotFoundException: class path resource [xxx.properties] cannot be opened because it does not exist
或
application.properties/yml 的配置没有生效(SpringBoot项目)
所以我们正常的解决思路是如下:
虽然这确实是正解,但是:并不是所有资源都一定要被编译进入项目名\target\classes
才能被外部访问,比如src/main/webapp
下的静态资源,它就不被编译到classes目录
却可以直接被访问到。
今天,我就同时遇到(
SpringBoot项目中
)
appliacation.yml
配置无效src/main/webapp
下的JSP模板一直访问不到报404
由于两个错误同时出现,解决了第一个问题后,我一直都在考虑编译没的问题,耽误了很长时间,后来发现是:使用了JSP模板,却没有导入默认渲染类
"org.apache.jasper.servlet.JspServlet"
产生的JSP访问不到的问题。
- 详细内容可见:SpringBoot项目打成jar与war的区别
- 下面我来剖析下:
- 为什么
src/main/resources
下的静态资源要被编译进入项目名\target\classes
才能被外部访问,而src/main/webapp
下的静态资源,无需编译可以直接被访问到??
- 为什么
- 具体区别表现可见:SpringBoot项目打成jar与war的区别
src/main/resources:
放代码:
/**
* Create a new DefaultResourceLoader.
* <p>ClassLoader access will happen using the thread context class loader
* at the time of this ResourceLoader's initialization.
* @see java.lang.Thread#getContextClassLoader()
*/
public DefaultResourceLoader() {
this.classLoader = ClassUtils.getDefaultClassLoader();
}
这段代码,是Spring获得自己的默认资源加载器
的过程,我们还知道Spring提供了ResourceHttpRequestHandler
来配置src/main/resources(classpath)
下指定访问目录,而DefaultResourceLoader(默认的资源加载器)
本质上就是DefaultClassLoader(默认的类加载器)
,而类加载器
主要是针对**.class
文件的路径,所以此时我们可以理解:为什么src/main/resources(classpath)
的静态资源也需要编译到classes目录
下?
src/main/webapp:
对于webapp我们似乎更容易理解,它主要是通过servlet container
的ContextPath
来确定资源在文件系统中
的位置,然后使用如下API从文件系统
中获取对应资源
: