十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
怎么在Spring Boot中实现Fat Jar jsp的支持?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联公司主要从事成都网站制作、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务昂昂溪,10多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792
spring boot 对于jsp支持的限制
对于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官方说是tomcat的问题,实际上是spring boot自己改变了打包格式引起的。参考之前的文章:https://www.jb51.net/article/141479.htm
原来的结构之下,tomcat是可以扫描到fat jar里的META-INF/resources
目录下面的资源的。在增加了BOOT-INF/classes
之后,则tomcat扫描不到了。
那么怎么解决这个问题呢?下面给出一种方案,来实现对spring boot fat jar/exploded directory的jsp的支持。
个性化配置tomcat,把BOOT-INF/classes 加入tomcat的ResourceSet
在tomcat里,所有扫描到的资源都会放到所谓的ResourceSet
里。比如servlet 3规范里的应用jar包的META-INF/resources
就是一个ResourceSet
。
现在需要想办法把spring boot打出来的fat jar的BOOT-INF/classes
目录加到ResourceSet
里。
下面通过实现tomcat的 LifecycleListener接口,在Lifecycle.CONFIGURE_START_EVENT事件里,获取到BOOT-INF/classes的URL,再把这个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加载这个 StaticResourceConfigurer,还需要一个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)); } }); } } }; } }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。