springboot项目下的resources下的template的资源访问默认是要走servlet跳转,这里我们将静态资源放到webapp下,以便直接访问。
目录结构:(目标是运行后能直接访问webapp目录下资源)
这样设置好后,ide单独打开此工程运行完全正常,但是项目是多模块的,在idea中作为子模块运行会出现webapp目录资源404问题。
一:问题分析
1.查看springboot启动tomcat源码的类
切换到类org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory,找到获取资源方法。
查看getCommonDocumentRoot方法的逻辑发现是使用绝对路径。
2:问题分析
windows版本下的jdk8获取绝对路径使用了user.dir这个系统变量。debug一下System.getProperty("user.dir") 发现变量是输出了根工程的路径,这就解释了为啥单独打开模块能正常运行,作为子模块运行出现404了。
二:问题修复:
1:直接在idea中设置模块工作目录
2:使用外部tomcat运行
2.1、修改Spring Boot启动类
启动类继承 SpringBootServletInitializer
类,并覆盖 configure
方法。
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
Logger.getGlobal().info("application start");
}
}
2.2、修改jar为war包形式:
-
2.3、去除Spring Boot内置Tomcat(修改自带tomcat依赖范围为provided,防止与外部tomcat发生冲突)
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
-
2.4、添加war包打包插件:
如果你用的是继承spring-boot-starter-parent的形式使用Spring Boot,那可以跳过,因为它已经帮你配置好了。如果你使用的依赖spring-boot-dependencies形式,你需要添加以下插件:
-
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin>
-
接着配置本地tomcat运行:
运行效果: