【问题标题】:About modify spring boot 1.5.3 to support recognise jsp files关于修改spring boot 1.5.3 支持识别jsp文件
【发布时间】:2017-11-27 18:40:42
【问题描述】:

我用的是spring boot + jsp,从this post我知道如果把jsp文件放到src/main/resources/META-INF/resources/也可以打包成可执行jar。

不幸的是,当我将 spring boot 版本从 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(); 
}

春季启动 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的源代码复制到当前类路径

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

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

【问题讨论】:

    标签: jsp tomcat spring-boot


    【解决方案1】:

    我们这里有相同的 pb。

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

    ...

    原因: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. 最后似乎调用了“TomcatResources.get(context).addClasspathResources();”尚未删除但已重构。

    现在在 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 文件)。

    解决方案:我们只是删除了这个覆盖。 Jar 文件返回到类加载器中,因此存储在这些 jar 文件中的 jsp 文件现在可以被应用正确识别。

    【讨论】:

    • 但是我认为你可以为遗留项目做这个解决方法,但如果是一个新项目我建议你使用更高级的模板引擎,例如Thymeleaf,我觉得学习成本不是很高高。
    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 2017-09-28
    • 2017-10-28
    • 2017-10-04
    • 1970-01-01
    • 2021-01-23
    • 2021-05-30
    • 2017-03-06
    相关资源
    最近更新 更多