Apache Tiles + Spring MVC 在 jar 文件中提供 jsps

Apache Tiles + Spring MVC serves jsps inside jar files

目的
为 Web 项目设计 "add-on"。

Web 项目
我有一个打包为 WAR 的项目,它使用 Spring MVC 4.1.6 和 Apache Tiles 3.0.5 作为 UI 框架。这是应用程序上下文的示例:

<bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer" id="tilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/foo/bar/layouts.xml</value>
            <value>classpath:/META-INF/ext/**/views.xml</value><!-- For add-ons -->
        </list>
    </property>
</bean>

JAR
我还有另一个 JAR,它是 "add-on"。这个 jar 需要包含一些 jsp 文件。一般的想法是,如果我从 /WEB-INF/lib 目录中删除这个 jar,当我重新启动 Web 服务器时,所有相关的功能都将被删除。同样,当我将 jar 放入 lib 目录时,所有相关功能都将可用。样本图块定义 (views.xml):

<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
    <definition extends="main" name="space">
        <!-- This does not work -->
        <put-attribute name="body" value="classpath:/META-INF/resources/index.jspx" />
    </definition>
</tiles-definitions>


1. JAR 文件中的 jsp 文件是否可以在 tiles 定义中定义?
2. 可以使用 web-fragment with/without 实现吗?

不知何故,我设法找到了解决方案。

  1. 创建一个 class 在您的 jar 中实现 ServletContainerInitializer。覆盖方法并添加 servlet 映射,如下所示:

    @Override
    public void onStartup(final Set<Class<?>> clazzes, final ServletContext servletContext) throws ServletException {
        final ServletRegistration servletRegistration = servletContext.addServlet("name-of-servlet-declared-in-web.xml", DispatcherServlet.class);
        servletRegistration.addMapping("/name-of-tiles-definition");
    }
    
  2. 在您的 jar 中的 tiles 定义中,映射在 #1 中添加的定义名称。

    <tiles-definitions>
        <definition extends="main" name="name-of-tiles-definition">
            <put-attribute name="body" value="/path-to-resource/jsp-name.jspx" />
        </definition>
    </tiles-definitions>
    
  3. 在“/META-INF/services”目录中创建名称为 "javax.servlet.ServletContainerInitializer" 的文件。此文件中应包含 ServletContainerInitializer 实现的 FQDN。

  4. 至于您的 JSP,请将它们放在“/META-INF/resources/”目录下。例如,如果您的 JSP 位于“/META-INF/resources/example”下,在 #2 中,"put-attribute" 元素的值将是“/example/jsp-name.jspx”。

  5. 最后,在“/META-INF”目录中创建您的 web-fragment.xml 文件。我的 web-fragment.xml 只包含 "display.name" 元素。我不确定这个文件是否必要,但因为它对我有用,所以我想我会让它存在于我的硬盘中。

在我的 jar 中,我还有 Controllers 和 i18n 属性文件,它们在 servlet-context 中定义,在 main web.xml.

中加载和初始化

让我知道这是否适合您。 HTH.