在Spring中如何使用多个ViewResolvers?


问题内容

我正在使用一个Web应用程序,其中我的大部分页面都使用apache tile(2.1.2),但是其中一些仅是纯jsps。

我遇到的一个问题是,无论哪种情况,an InternalResourceViewResolver和a
UrlBasedViewResolver都将尝试解析该视图,因此无论我使用哪种顺序,它都将在纯JSP页面或切片页面上失败。

这是配置:

<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    <property name="order" value="0"/>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
    <property name="order" value="1"/>
</bean>

为了更清楚地说明我要执行的操作,我需要具有以下视图状态:

<view-state id="someState" view="/someDir/foo"><!--render foo.jsp -->
    <transition on="foo" to="bar"/>
</view-state>

<view-state id="someState" view="something.core"><!--render tile defintion named 'something.core' -->
    <transition on="foo" to="bar"/>
</view-state>

有谁知道如何配置东西,以便我可以渲染图块定义和普通的jsps?


问题答案:

如您所说,您不能将它们链接在一起。两者的javadoc都明确指出,它们都必须都在解析程序链的末尾。

我建议如果您确实需要使用这些集合,那么您可以编写一个简单的ViewResolver自定义实现,该实现采用视图名称,并确定要委派给两个“真实”视图解析器中的哪个。假设您可以根据视图名称确定要调用哪个解析器。


因此,您需要像这样定义自定义ViewResolver:

public class MyViewResolver implements ViewResolver {

    private ViewResolver tilesResolver;
    private ViewResolver jspResolver;

    public void setJspResolver(ViewResolver jspResolver) {
        this.jspResolver = jspResolver;
    }

    public void setTilesResolver(ViewResolver tilesResolver) {
        this.tilesResolver = tilesResolver;
    }

    public View resolveViewName(String viewName, Locale locale) throws Exception {
        if (isTilesView(viewName)) {
            return tilesResolver.resolveViewName(viewName, locale);
        } else {
            return jspResolver.resolveViewName(viewName, locale);
        }
    }

    private boolean isTilesView(String viewName) {
    .....
    }
}

您需要实现isTilesView方法来确定要委派给哪个解析器。

在XML配置中,定义这个新的视图解析器,并确保它出现 其他视图解析器 之前

<bean class="MyViewResolver">
    <property name="tilesResolver" ref="tilesViewResolver"/>
    <property name="jspResolver" ref="viewResolver"/>
</bean>