0

这是一个复杂的问题,所以请耐心等待我的冗长解释。

当前情景

我们使用 Spring MVC 3.0.5 和 Apache Tiles 2.2。目前我们基于 Spring 的瓦片配置如下所示:

<bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/**/views.xml</value>
        </list>
    </property>

    <!-- resolving preparer names as Spring bean definition names -->
    <property name="preparerFactoryClass" 
        value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory" />
</bean>

<bean id="tilesViewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver"
    p:order="1" p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView" />

从所有文件中读取(Tiles)视图定义views.xml,当 Spring 控制器产生,例如,“主页”作为要呈现的逻辑视图名称时,将显示名称为“主页”的相应 Tiles 定义。

目标

我们现在打算在我们的 Web 应用程序中允许来自不同目录的不同视图定义集。原因是,不同的用户组将根据他们的组定制模板。

假设我当前的所有视图定义都位于

 /WEB-INF/default-views/**/views.xml

我想添加第二个文件夹

 /WEB-INF/administrator-views/**/views.xml

第二个文件夹应包含与文件夹中名称相同的视图定义default-views。但根据 URL 模式,应显示其中一个或另一个。以下是两个示例:

http://example.com/default/foobar 
==> Controller yields logical view name "foobar"
==> definition "foobar" from "default-views" folder shall be displayed

http://example.com/admin/foobar 
==> Controller yields logical view name "foobar"
==> definition "foobar" from "administrator-views" folder shall be displayed

此外,我们希望允许回退机制。当相应的视图文件夹中不存在专用视图名称(上例中的“admin”)时,我们希望显示其他文件夹中的默认版本。

至今

目前我正在考虑几个起点。也许我可以调整TilesConfigurer. 它将 Tiles 视图定义保留在单个属性中,而不区分视图定义来自的文件夹。

另一种选择是尝试使用链式视图解析器来完成此任务,其中专用的视图解析器位于链的更上方,默认的解析器位于最后。

第三种选择是使用不同的视图名称并拦截来自控制器的视图名称响应,使用 aHandlerInterceptor将其映射到专用视图(如果它不存在则可能不起作用)。

问题

  • 实现这种视图解析机制有哪些好的选择?
    • 允许视图定义被其他人/更专业的人覆盖
    • 根据请求的 URL 模式进行显示

目前,我的选项#2 听起来最有说服力,因为我想防止在没有必要时玩弄 Springs 类。但是我缺少链式视图解析器和TilesConfigurer.

感谢您到目前为止的耐心和阅读。

4

1 回答 1

2

对于可能遇到此类问题的任何人,以下是我们实施它的方式:

  • 使用自定义HandlerInterceptorAdapter#postHandle(..)实现将 URL 路径组件转换为逻辑视图名称前缀
  • views.xml在所有文件中使用带有这些 URL 前缀的 Tiles 视图定义名称
  • 使用自定义UrlBasedViewResolver#loadView(..)实现首先尝试由Controllerand给出的视图名称HandlerInterceptor,如果它不存在(super.loadView(..)产生 null)尝试使用默认前缀

我希望这足够清楚。

于 2011-04-15T16:52:58.673 回答