Fat Jar jsp 지원을 위한 Spring Boot 심화

4810 단어 SpringBootFatJarjsp
spring boot jsp 지원에 대한 제한
jsp의 지원에 대해 Spring Boot 공식은war의 포장 방식만 지원하고fatjar는 지원하지 않습니다.공식 문서 참조: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-jsp-limitations
여기springboot는 공식적으로tomcat의 문제라고 하는데, 실제로springboot이 스스로 포장 형식을 바꾸어서 일어난 것이다.이전 기사 참조: https://www.jb51.net/article/141479.htm
원래의 구조 아래tomcat은fatjar의 META-INF/resources 디렉터리 아래의 자원을 스캔할 수 있다.BOOT-INF/classes이 증가한 후에tomcat 스캐닝이 불가능합니다.
그러면 이 문제를 어떻게 해결합니까?스프링bootfatjar/explodeddirectory에 대한 jsp 지원을 위한 방안을 제시합니다.
맞춤형 설정tomcat, BOOT-INF/classes를tomcat의 ResourceSet에 추가
tomcat에서 스캔한 모든 자원은 이른바 ResourceSet 안에 넣는다.예를 들어 servlet3규범에 응용된jar패키지META-INF/resources는 하나ResourceSet이다.
스프링부트에서 나온 fatjar의 BOOT-INF/classes 디렉터리를 ResourceSet 에 추가할 방법을 강구해야 합니다.
다음은tomcat을 실현하는 LifecycleListener 인터페이스를 통해 Lifecycle에 있습니다.CONFIGURE_START_이벤트 이벤트에서 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");

  }
 }
}
이 StaticResourceConfigurer를 spring boot embedded tomcat에 로드하려면 Embedded Servlet Container Customizer 구성이 필요합니다.

@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));
        }
       });
    }
   }

  };
 }
}
이렇게 하면springboot은fatjar의 jsp자원을 지원할 수 있습니다.
demo 주소: https://github.com/hengyunabc/spring-boot-fat-jar-jsp-sample
총결산
  • springboot이 패키지 구조를 바꾸어tomcat이fatjar에 스캔할 수 없음/BOOT-INF/classes
  • 하나StaticResourceConfigurer를 통해fatjar의/BOOT-INF/classes를tomcat의ResourceSet에 추가하여 문제를 해결
  • 이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

    좋은 웹페이지 즐겨찾기