代码之家  ›  专栏  ›  技术社区  ›  TM. Randy Simon

如何在Spring中使用多个ViewResolver?

  •  17
  • TM. Randy Simon  · 技术社区  · 15 年前

    我在这两方面都有问题 InternalResourceViewResolver UrlBasedViewResolver 无论发生什么,我都会尝试解析视图,这样无论我使用哪种顺序,它要么在普通JSP页面上失败,要么在tiles页面上失败。

    <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>
    

    有人知道如何配置东西,以便我可以让它呈现平铺定义和普通JSP吗?

    5 回复  |  直到 15 年前
        1
  •  22
  •   skaffman    15 年前

    正如你所说,你不能把它们连在一起。这两个的javadoc都清楚地指出,它们都必须位于解析器链的末尾。


    因此,您可以这样定义自定义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方法来决定委托给哪个解析器。

    之前

    <bean class="MyViewResolver">
        <property name="tilesResolver" ref="tilesViewResolver"/>
        <property name="jspResolver" ref="viewResolver"/>
    </bean>
    
        2
  •  3
  •   kryger    12 年前

    我刚刚通过拆分文件解决了同样的问题 *-servlet.xml

    app-servlet.xml 仅包含平铺视图解析程序, tests-servlet.xml 仅包含JSP视图解析器和 web.xml

    <servlet-mapping>
      <servlet-name>app</servlet-name> <!-- will reach app-servlet.xml -->
      <url-pattern>/foo</url-pattern> <!-- will use "foo" Tile -->
      <url-pattern>/bar</url-pattern> <!-- will use "bar" Tile -->
    </servlet-mapping>
    
    <servlet-mapping>
      <servlet-name>tests</servlet-name> <!-- will reach tests-servlet.xml -->
      <url-pattern>/foo-test</url-pattern> <!-- will use foo-test.jsp -->
      <url-pattern>/bar-test</url-pattern> <!-- will use bar-test.jsp -->
    </servlet-mapping>
    
        3
  •  1
  •   Jherico    15 年前

    看起来您走的方向是正确的,但要记住的是,某些视图解析程序的行为似乎总是解析视图。您需要确保在订购时将此类解析器放在最后。我相信瓦片的观点就是这样。

    编辑:哎呀。。。是的,另一张海报是正确的,这两个解析器都将执行“始终匹配”,因此不能在链中同时使用它们。另一种替代方法是,如果无法找到已配置的平铺视图,则尝试扩展平铺视图以执行简单的JSP呈现。

        4
  •  0
  •   Nirbhay Mishra    10 年前

    因此,您可以在同一项目中同时使用“平铺视图解析器”和“内部视图解析器”。

    您必须配置ContentNegotingViewResolver。

    并在视图解析程序中指定顺序值。

    <property name="order" value="int Value here" />
    

    以下是一些适合我的配置。

        <bean
            class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
            <property name="order" value="1" />
            <property name="mediaTypes">
                <map>
                    <entry key="json" value="application/json" />
                    <entry key="html" value="text/html" />
                </map>
            </property>
            <property name="parameterName" value="accept"></property>
            <property name="favorParameter" value="true"></property>
            <property name="defaultContentType" value="text/html"></property>
            <property name="viewResolvers">
                <list>
                    <ref bean="tilesViewResolver" />
                    <ref bean="internalViewResolver" />
                </list>
            </property>
            <property name="defaultViews">
                <list>
                    <bean
                        class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
                </list>
            </property>
            <property name="ignoreAcceptHeader" value="true" />
        </bean>
    
    <!--    Configures the Tiles layout system  -->
        <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
            id="tilesConfigurer">
            <property name="definitions">
                <list>
                    <value>/WEB-INF/layouts/layouts.xml</value>
                <!-- Scan views directory for Tiles configurations  -->
                    <value>/WEB-INF/views/**/views.xml</value>
                </list>
            </property>
        </bean>
        <bean id="tilesViewResolver"
            class="org.springframework.web.servlet.view.UrlBasedViewResolver"
            p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView">
            <property name="order" value="3" />
        </bean>
    
    
        <bean id="internalViewResolver"
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="order" value="2" />
            <property name="prefix">
                <value>/WEB-INF/views/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>
    
        5
  •  0
  •   Andrey Sarul    9 年前

    我通过简单地为普通jsp的布局添加平铺定义来解决这个问题,如下所示:

      <definition name="plain-jsp.layout" template="/WEB-INF/layouts/plainJsp.jspx" >
        <put-attribute name="content" value=""/>
      </definition>
    

    然后您就可以使用这个布局作为包含简单jsp文件的模板。

      <definition name="catalog/details" extends="plain-jsp.layout">
        <put-attribute name="content" value="/WEB-INF/views/catalog/details.jspx"/>
      </definition>
    

    和布局模板文件:

    <html xmlns:tiles="http://tiles.apache.org/tags-tiles"
          xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
    
      <jsp:output doctype-root-element="HTML"/>
      <jsp:directive.page contentType="text/html;charset=UTF-8" />  
      <jsp:directive.page pageEncoding="UTF-8" />
    
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=8" />      
      </head>
      <body>
        <div id="content">
          <tiles:insertAttribute name="content"/>
        </div>
      </body>
    </html>