Frage

Ich arbeite an einer Web-Anwendung, wo ich die meisten meiner Seiten unter Verwendung von Apache Fliesen haben (2.1.2), aber einige von ihnen müssen einfach nur jsps sein.

Ich habe ein Problem, dass sowohl ein InternalResourceViewResolver und ein UrlBasedViewResolver wird versuchen, die Ansicht, egal was zu lösen, so dass unabhängig davon, welche Bestellung ich verwende, wird es entweder auf der Ebene JSP-Seiten scheitern, oder auf den Fliesen Seiten .

Hier ist die config:

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

Um es klar, was ich zu tun versuchen, ich brauche Ansicht Zustände wie diese haben zu können:

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

Wer weiß, wie die Dinge so zu konfigurieren, dass ich es bekommen kann Fliesen Definitionen und Klar jsps zu machen?

War es hilfreich?

Lösung

Wie Sie sagen, dass Sie nicht Kette dieser zusammen. Die javadoc für beide eindeutig fest, dass sie beide am Ende der Resolver-Kette sein muss.

Ich schlage vor, dass, wenn Sie wirklich diese togather verwenden müssen, dann Sie eine einfache benutzerdefinierte Implementierung von ViewResolver schreiben, die den Namen der Ansicht nimmt und entscheidet, welche Ihrer beiden „echten“ Ansicht Resolvern zu delegieren. Dies setzt voraus, dass man sagen kann, die auf den Namen der Ansicht basierend anrufen Resolver.


So haben Sie eine benutzerdefinierte ViewResolver wie folgt definieren würde:

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

Sie müssen die isTilesView Methode zu implementieren, um zu entscheiden, welche zu delegieren Resolver.

In der XML-Konfigurations definieren diese neue Ansicht Resolver, und stellen Sie sicher, dass es erscheint vor die anderen.

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

Andere Tipps

Ich habe gelöst gerade das gleiche Problem, indem die *-servlet.xml Config-Datei in zwei aufzuteilen; in meinem Fall verwendet die Hauptanwendung Fliesen, aber ich will QUnit Tests einfach JSPs sein.

app-servlet.xml enthält nur die Fliesen Ansicht Resolver, tests-servlet.xml enthält nur die JSP Ansicht Resolver und web.xml Zuordnungen Anforderungen an den richtigen Servlet Dispatching auf der URL zu stützen.

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

Es sieht aus wie Sie auf dem richtigen Weg sind, aber die Sache im Auge zu behalten ist, dass einige Ansicht Resolvern verhalten, als ob sie immer die Ansicht gelöst haben. Sie müssen sicherstellen, dass solche Resolvern zuletzt in Ihrer Bestellung setzen. Ich glaube, die Fliesen Ansicht ist eine solche.

Edit: hoppla ... ja, das andere Plakat korrekt ist, wird diese beiden Resolvern tun ‚immer passen‘, so dass Sie nicht sie beide in einer Kette verwenden können. Eine andere alternative wäre zu versuchen, die TilesView zu erweitern, um eine einfache JSP machen zu tun, wenn es kann nicht über eine konfigurierte Kachel-Ansicht finden.

Ja, Sie eine beliebige Anzahl von Ansicht Resolver in Ihrem Projekt verwenden können.

So verwenden Sie können sowohl ‚Kacheln anzeigen Resolver‘ und ‚Innenansicht Resolver‘ in demselben Projekt. .

Sie müssen einen ContentNegotiatingViewResolver konfigurieren. .

und Auftragswert aus Ihrer Sicht Resolvern geben.

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

wie ich gegeben Fliesen sehen Resolver 2 und internalviewresolver 3. .Es wird zuerst in Kacheln Definitionen prüfen, ob eine Ansicht nicht in Kacheln gefunden wird es in InternaiViewResolver geprüft werden

Hier ist einige Konfigurationen, die für mich funktioniert.

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

beschloß ich dieses Problem durch einfaches Hinzufügen von Fliesen Definition für Layout Ebene jsp ist, wie folgt aus:

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

Dann können Sie dieses Layout als Vorlage verwenden für Ihre einfache jsp Dateien enthält.

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

Und Layout-Vorlage-Datei:

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top