深入Spring Boot實(shí)現(xiàn)對(duì)Fat Jar jsp的支持
spring boot 對(duì)于jsp支持的限制
對(duì)于jsp的支持,Spring Boot官方只支持了war的打包方式,不支持fat jar。參考官方文檔: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-jsp-limitations
這里spring boot官方說(shuō)是tomcat的問(wèn)題,實(shí)際上是spring boot自己改變了打包格式引起的。參考之前的文章:http://chabaoo.cn/article/141479.htm
原來(lái)的結(jié)構(gòu)之下,tomcat是可以掃描到fat jar里的META-INF/resources
目錄下面的資源的。在增加了BOOT-INF/classes
之后,則tomcat掃描不到了。
那么怎么解決這個(gè)問(wèn)題呢?下面給出一種方案,來(lái)實(shí)現(xiàn)對(duì)spring boot fat jar/exploded directory的jsp的支持。
個(gè)性化配置tomcat,把BOOT-INF/classes 加入tomcat的ResourceSet
在tomcat里,所有掃描到的資源都會(huì)放到所謂的ResourceSet
里。比如servlet 3規(guī)范里的應(yīng)用jar包的META-INF/resources
就是一個(gè)ResourceSet
。
現(xiàn)在需要想辦法把spring boot打出來(lái)的fat jar的BOOT-INF/classes
目錄加到ResourceSet
里。
下面通過(guò)實(shí)現(xiàn)tomcat的 LifecycleListener接口,在Lifecycle.CONFIGURE_START_EVENT事件里,獲取到BOOT-INF/classes的URL,再把這個(gè)URL加入到WebResourceSet里。
/** * Add main class fat jar/exploded directory into tomcat ResourceSet. * * @author hengyunabc 2017-07-29 * */ public class StaticResourceConfigurer implements LifecycleListener { private final Context context; StaticResourceConfigurer(Context context) { this.context = context; } @Override public void lifecycleEvent(LifecycleEvent event) { if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation(); if (ResourceUtils.isFileURL(location)) { // when run as exploded directory String rootFile = location.getFile(); if (rootFile.endsWith("/BOOT-INF/classes/")) { rootFile = rootFile.substring(0, rootFile.length() - "/BOOT-INF/classes/".length() + 1); } if (!new File(rootFile, "META-INF" + File.separator + "resources").isDirectory()) { return; } try { location = new File(rootFile).toURI().toURL(); } catch (MalformedURLException e) { throw new IllegalStateException("Can not add tomcat resources", e); } } String locationStr = location.toString(); if (locationStr.endsWith("/BOOT-INF/classes!/")) { // when run as fat jar locationStr = locationStr.substring(0, locationStr.length() - "/BOOT-INF/classes!/".length() + 1); try { location = new URL(locationStr); } catch (MalformedURLException e) { throw new IllegalStateException("Can not add tomcat resources", e); } } this.context.getResources().createWebResourceSet(ResourceSetType.RESOURCE_JAR, "/", location, "/META-INF/resources"); } } }
為了讓spring boot embedded tomcat加載這個(gè) StaticResourceConfigurer,還需要一個(gè)EmbeddedServletContainerCustomizer的配置:
@Configuration @ConditionalOnProperty(name = "tomcat.staticResourceCustomizer.enabled", matchIfMissing = true) public class TomcatConfiguration { @Bean public EmbeddedServletContainerCustomizer staticResourceCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (container instanceof TomcatEmbeddedServletContainerFactory) { ((TomcatEmbeddedServletContainerFactory) container) .addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.addLifecycleListener(new StaticResourceConfigurer(context)); } }); } } }; } }
這樣子的話,spring boot就可以支持fat jar里的jsp資源了。
demo地址: https://github.com/hengyunabc/spring-boot-fat-jar-jsp-sample
總結(jié)
- spring boot改變了打包結(jié)構(gòu),導(dǎo)致tomcat沒(méi)有辦法掃描到fat jar里的/
BOOT-INF/classes
- 通過(guò)一個(gè)
StaticResourceConfigurer
把fat jar里的/BOOT-INF/classes
加到tomcat的ResourceSet
來(lái)解決問(wèn)題
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot集成RabbitMQ的方法(死信隊(duì)列)
這篇文章主要介紹了SpringBoot集成RabbitMQ的方法(死信隊(duì)列),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05Java數(shù)據(jù)結(jié)構(gòu)之鏈表(動(dòng)力節(jié)點(diǎn)之Java學(xué)院整理)
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之鏈表(動(dòng)力節(jié)點(diǎn)之Java學(xué)院整理)的相關(guān)資料,需要的朋友可以參考下2017-04-04Spring加載屬性文件方式(自動(dòng)加載優(yōu)先級(jí)問(wèn)題)
這篇文章主要介紹了Spring加載屬性文件方式(自動(dòng)加載優(yōu)先級(jí)問(wèn)題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02spring?boot中spring框架的版本升級(jí)圖文教程
Spring Boot是一款基于Spring框架的快速開(kāi)發(fā)框架,它提供了一系列的開(kāi)箱即用的功能和組件,這篇文章主要給大家介紹了關(guān)于spring?boot中spring框架的版本升級(jí)的相關(guān)資料,需要的朋友可以參考下2023-10-10spring 中事務(wù)注解@Transactional與trycatch的使用
這篇文章主要介紹了spring 中事務(wù)注解@Transactional與trycatch的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06