关于修改spring boot 1.5.3以支持识别jsp文件

时间:2017-06-24 07:32:43

标签: jsp tomcat spring-boot

我使用了spring boot + jsp,并且来自this post我知道在src/main/resources/META-INF/resources/中放置jsp文件是否也可以打包为可执行jar。

不幸的是,当我将弹簧启动版本从1.4.2修改为1.5.3时,它无法支持并返回404.在跟踪其源代码并进行比较后,我知道为什么1.5.3无法支持它。

Spring boot 1.4.2

//org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.StoreMergedWebXmlListener#onStart
private void onStart(Context context) {
    ServletContext servletContext = context.getServletContext();
    if(servletContext.getAttribute("org.apache.tomcat.util.scan.MergedWebXml") == null) {
        servletContext.setAttribute("org.apache.tomcat.util.scan.MergedWebXml", this.getEmptyWebXml());
    }
    // only 1.4.2 has this line and with this code could recognise jsp files in /META-INF/resources/
    TomcatResources.get(context).addClasspathResources(); 
}

Spring boot 1.5.3

private void onStart(Context context) {
    ServletContext servletContext = context.getServletContext();
    if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
        servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
    }
}

所以我想知道为什么在1.4.2之后必须删除这段代码?

TomcatResources.get(context).addClasspathResources(); 

因为我仍然想使用1.5.3所以我必须通过以下方式手动添加此代码

1.将TomcatEmbeddedServletContainerFactory的源代码复制到当前类路径 enter image description here

2.以下修改

private void onStart(Context context) {
    ServletContext servletContext = context.getServletContext();
    if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
        servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
    }
    // Add below code
    ClassLoader loader = getClass().getClassLoader();
    URL[] urLs = ((URLClassLoader) loader).getURLs();
    List<URL> list = new ArrayList<>();
    //String file = "file:/Users/zhugw/workspace/boot-jar-serving-jsp/boot-jar-serving-jsp-1.0-SNAPSHOT.jar!/";
    String file = urLs[0].getFile().replaceFirst("BOOT-INF/classes!/", "");
    URL jar = new URL("jar", "", file);
    list.add(0,jar);
    TomcatResources.get(context).addResourceJars(list);
} 

它确实有效。我想知道是否可以这样做?

1 个答案:

答案 0 :(得分:1)

我们在这里有相同的pb。

  1. 我们尝试了您的解决方案,但未成功。启动应用程序时引发了以下异常:
  2.   

    ...

         

    引起:java.lang.IllegalAccessError:试图访问类   org.springframework.boot.context.embedded.tomcat.TldSkipPatterns来自   类   org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory         在org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory。(TomcatEmbeddedServletContainerFactory.java:130)

         

    ...

    1. 最后似乎调用了#34; TomcatResources.get(context).addClasspathResources();&#34;尚未删除但已重构。
    2. 现在在SpringBoot 1.5.8.RELEASE中,TomcatEmbeddedServletContainerFactory.prepareContext()中有以下几行:

      context.addLifecycleListener(new LifecycleListener() {
          @Override
          public void lifecycleEvent(LifecycleEvent event) {
              if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
                  TomcatResources.get(context)
                          .addResourceJars(getUrlsOfJarsWithMetaInfResources());
              }
          }
      });
      
      1. 在我们的例子中,我们使用了自定义的EmbeddedServletContainerFactory(覆盖了TomcatEmbeddedServletContainerFactory的一些方法),并且由于未知原因,在getUrlOfJarsWithMetaInfResources()中检索的类加载器几乎为空(只有没有jar文件的classes文件夹)。
      2. 解决方案:我们只是删除了此覆盖。 Jar文件在类加载器中是后备的,因此应用程序可以正确识别存储在这些jar文件中的jsp文件。