Spring工程访问src/main/resources与src/main/webapp下静态资源的区别

由于高版本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项目)

所以我们正常的解决思路是如下:

Created with Raphaël 2.1.2 右键工程文件 buildpath sources 工程名/src/main/resources Excluded:** Remove

这里写图片描述

虽然这确实是正解,但是:并不是所有资源都一定要被编译进入项目名\target\classes才能被外部访问,比如src/main/webapp下的静态资源,它就不被编译到classes目录却可以直接被访问到。

今天,我就同时遇到(SpringBoot项目中

  • appliacation.yml配置无效
  • src/main/webapp下的JSP模板一直访问不到报404

由于两个错误同时出现,解决了第一个问题后,我一直都在考虑编译没的问题,耽误了很长时间,后来发现是:使用了JSP模板,却没有导入默认渲染类"org.apache.jasper.servlet.JspServlet"产生的JSP访问不到的问题。

  • 下面我来剖析下:
    • 为什么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 containerContextPath来确定资源在文件系统中的位置,然后使用如下API从文件系统中获取对应资源
    这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_32331073/article/details/81556994