我正在开发一个网络应用程序,我的大部分页面都使用了apache tiles(2.1.2),但其中一些只需要简单的jsps。

我遇到的问题是, InternalResourceViewResolver UrlBasedViewResolver 都会尝试解析视图,无论如何,所以无论我使用哪种顺序,它都是将在纯JSP页面或tile页面上失败。

这是配置:

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

有没有人知道如何配置东西,以便我可以让它来渲染tile定义和普通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>

其他提示

我刚刚将 * - servlet.xml 配置文件分成两部分解决了同样的问题;在我的例子中,主应用程序使用Tiles,但我希望QUnit测试是简单的JSP。

app-servlet.xml 仅包含Tiles视图解析程序, tests-servlet.xml 仅包含JSP视图解析程序和 web.xml 映射根据URL将请求分派给正确的servlet。

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

看起来你走在正确的轨道上,但要记住的是,一些视图解析器的行为就像它们总是解析了视图一样。您需要确保在订购时将这些解析器放在最后。我相信Tiles视图就是其中之一。

编辑:哎呀...是的,另一张海报是正确的,这两个解析器都会“始终匹配”,所以你不能在链中使用它们。另一个替代方法是尝试扩展TilesView,以便在无法找到已配置的平铺视图时执行简单的JSP渲染。

是的,您可以在项目中使用任意数量的视图解析器。

因此,您可以在同一个项目中使用'tiles View resolver'和'Internal view resolver'。

您必须配置ContentNegotiatingViewResolver。 。

并在视图解析器中提供订单值。

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

就像我已经给出了tile视图解析器2和internalviewresolver 3.它将首先检查tile定义,如果在tile中找不到视图,它将在InternaiViewResolver中检查

这里有一些适合我的配置。

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

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

  <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>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top