springboot打war包配置外部tomcat
pom.xml中的配置
- 添加
<packaging>war</packaging> - 排除tomcat依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 添加servlet-api依賴
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
啟動類配置
繼承SpringBootServletInitializer并重寫configure方法
public class ImageStorageApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ImageStorageApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ImageStorageApplication.class);
}
}
完成上述配置就可以打war包在外部tomcat中啟動了,但是在配置過程中,我依然遇到了幾個問題
問題
- 無法使用ServletContextListener,該監(jiān)聽器可以監(jiān)聽Context也就是容器的創(chuàng)建和銷毀,在springboot中使用是沒有問題的,但是在外部tomcat中會報錯,原因暫不明確,如果要監(jiān)聽容器創(chuàng)建,可以繼承
ApplicationRunner,并重寫run方法。如果想在容器銷毀時做一些事兒,暫時沒找到好的辦法。 - Filter相關(guān)
- springboot的Filter和外部Tomcat的Filter是有區(qū)別的,springboot的Filter的init()和destroy()方法都是default的,但是外部tomcat的這兩個方法都是抽象的,如果不重寫會報錯。
- springboot的啟動順序和外部tomcat不一樣,外部tomcat的Filter會在Spring容器之前初始化,也就是Filter中的@Autowire和@Value等注入屬性都是null,會報錯,解決方法是,設(shè)置成static,然后再賦值:
修改
@Value("${server.servlet.context-path}")
private String contentPath;
為:
private static String contentPath;
@Value("${server.servlet.context-path}")
public void setContentPath(String contentPath) {
LoginFilter.contentPath = contentPath;
}