溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在Spring Boot中實現(xiàn)Fat Jar jsp的支持

發(fā)布時間:2021-06-04 17:00:30 來源:億速云 閱讀:141 作者:Leah 欄目:編程語言

怎么在Spring Boot中實現(xiàn)Fat Jar jsp的支持?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

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

原來的結(jié)構(gòu)之下,tomcat是可以掃描到fat jar里的META-INF/resources目錄下面的資源的。在增加了BOOT-INF/classes之后,則tomcat掃描不到了。

那么怎么解決這個問題呢?下面給出一種方案,來實現(xiàn)對spring boot fat jar/exploded directory的jsp的支持。

個性化配置tomcat,把BOOT-INF/classes 加入tomcat的ResourceSet

在tomcat里,所有掃描到的資源都會放到所謂的ResourceSet里。比如servlet 3規(guī)范里的應(yīng)用jar包的META-INF/resources就是一個ResourceSet。

現(xiàn)在需要想辦法把spring boot打出來的fat jar的BOOT-INF/classes目錄加到ResourceSet里。

下面通過實現(xiàn)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));
        }
       });
    }
   }

  };
 }
}

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI