Springboot项目打 jar 包没有webapp中的静态资源

问题发生场景

以下场景都建立在 maven 打 jar 包的基础上。

昨日我如往常一样,在springboot项目中新建 webapp 文件夹,然后在里面放俩空文件夹,作为项目里文件上传中转的地方。然后发现打包后程序运行时并不能找到webapp文件夹中的静态资源。查看编译后产生的 target 目录发现,webapp并没有被编译。如下图所示。

webapp未编译

而平时开发,直接通过 idea 运行的时候,却会编译 webapp 下的资源文件到 classes 目录下。如下图所示。

idea直接运行

解决方案

如果跟我一样不愿意放弃 webapp 的使用,那么想要解决这个问题,就需要手动指定项目构建时的资源路径。

在 pom.xml 文件的 build 标签中,添加以下代码,手动指定资源路径。

1
2
3
4
5
6
7
8
9
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>

ps:这样只指定webapp的路径的话,resource 中的 static 和 template 就不会被编译了。要是都想要的话,就得都手动指定。

也就是说,springboot 使用 maven编译时,默认只寻找 resources 中的静态资源,而忽略 webapp。

附加

自问:为什么我以前学习 spring mvc 的时候,用 webapp 文件夹存放静态资源没有任何问题呢?

自答:非要说 springboot 和 spring mvc 直观上有哪里不太一样的话,那就是打包方式了。以前学习 spring mvc 的时候,都是打 war 包,然后部署到自己的 tomcat 服务器上。静态资源放在 webapp 中,而我似乎也一直是这么用的。但是当我学了spring boot后,项目都是在本地的idea直接运行,并没有正儿八经打包,然后手动部署过。因为 idea 自身会编译 webapp 下的文件,所以一直没有发现过问题。

所以另一种解决方案就是把 spring boot 打成 war 包。

PS

究其原因还是项目打成 jar 包和 war 包的区别。这里采用网上的描述。

  • jar文件包括java普通类、资源文件和普通文件,在maven中即是打包 src/main/java 和 src/main/resources 资源文件夹下的所有文件。在打包的时候会自动生成 META-INF 文件夹,用于存储 maven 的 pom 信息和 MANIFEST.MF 文件。(未包含 webapp 文件夹)

  • war文件包含全部的web应用程序,即所有的java类,配置信息和jsp、js等静态资源。(也就是说 webapp 文件夹也包含了)

或许这就是为什么学习 spring mvc 的时候我还在前后端一体, 而学习 spring boot 后却下意识的用起了前后端分离吧。码农的直觉?