20

我正在开发一个 web 应用程序,我的大部分页面都使用 apache tile (2.1.2),但其中一些只需要纯 jsps。

我遇到了一个问题,anInternalResourceViewResolver和 aUrlBasedViewResolver无论如何都会尝试解析视图,因此无论我使用哪种排序,它要么在普通 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?

4

5 回答 5

22

As you say, you cannot chain these together. The javadoc for both states clearly that they must both be at the end of the resolver chain.

I suggest that if you really need to use these togather, then you write a simple custom implementation of ViewResolver which takes the view name, and decides which of your two "real" view resolvers to delegate to. This assumes that you can tell which resolver to call based on the view name.


So you'd define a custom ViewResolver like this:

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) {
    .....
    }
}

You'd need to implement the isTilesView method to decide which resolver to delegate to.

In the XML config, define this new view resolver, and make sure it appears before the other ones.

<bean class="MyViewResolver">
    <property name="tilesResolver" ref="tilesViewResolver"/>
    <property name="jspResolver" ref="viewResolver"/>
</bean>
于 2009-06-22T20:23:54.023 回答
3

我刚刚通过将*-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>
于 2012-08-01T09:50:49.553 回答
1

It looks like you're on the right track, but the thing to bear in mind is that some view resolvers behave as if they have always resolved the view. You need to make sure to put such resolvers last in your ordering. I believe the Tiles view is one such.

Edit: whoops... yes, the other poster is correct, both of these resolvers will do 'always match' so you can't use them both in a chain. Another alterative would be to try to extend the TilesView to do a simple JSP render if it cant find a configured tile view.

于 2009-06-22T20:23:47.487 回答
0

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

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

你必须配置一个 ContentNegotiatingViewResolver 。.

并在您的视图解析器中给出订单价值。

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

就像我给了瓷砖视图解析器2和internalviewresolver 3一样。如果在瓷砖中找不到视图,它将首先检查瓷砖定义,它将在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>
于 2014-09-22T10:28:39.387 回答
0

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

  <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>
于 2016-05-14T21:24:18.767 回答