Question

Je travaille sur une application Web sur laquelle la plupart de mes pages utilisent des tuiles Apache (2.1.2), mais quelques-unes d'entre elles doivent n'être que de simples jsps.

Je rencontre un problème en ce qu'un InternalResourceViewResolver et un UrlBasedViewResolver essaieront de résoudre la vue quel que soit, de sorte que le type de commande que j'utilise échouera sur les pages JSP standard ou sur les pages de tuiles.

Voici la configuration:

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

Pour que ce que j'essaie de faire soit plus clair, il faut que je puisse avoir des états d'affichage tels que:

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

Quelqu'un sait-il comment configurer les choses pour que je puisse obtenir le rendu des définitions de tuiles et des jsps simples?

Était-ce utile?

La solution

Comme vous le dites, vous ne pouvez pas les lier ensemble. Le javadoc pour les deux états indique clairement qu'ils doivent tous les deux être à la fin de la chaîne de résolution.

Je suggère que si vous avez vraiment besoin d'utiliser ces méthodes de regroupement, écrivez une simple implémentation personnalisée de ViewResolver qui prend le nom de la vue et décide lequel de vos deux "vrais" afficher les résolveurs auxquels déléguer. Cela suppose que vous puissiez savoir quel résolveur appeler en fonction du nom de la vue.

Donc, vous définiriez un ViewResolver personnalisé comme ceci:

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

Vous devez implémenter la méthode isTilesView pour choisir le résolveur auquel déléguer.

Dans la configuration XML, définissez ce nouveau résolveur de vues et assurez-vous qu'il apparaisse avant les autres.

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

Autres conseils

Je viens de résoudre le même problème en scindant le fichier de configuration * - servlet.xml en deux; dans mon cas, l'application principale utilise les tuiles, mais je souhaite que les tests QUnit soient de simples JSP.

app-servlet.xml ne contient que le résolveur de la vue Tuiles, tests-servlet.xml contient uniquement le résolveur de la vue JSP et web.xml les mappages envoient des demandes au bon servlet en se basant sur l'URL.

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

Il semble que vous soyez sur la bonne voie, mais il convient de garder à l'esprit que certains résolveurs de vues se comportent comme s'ils l'avaient toujours résolue. Vous devez vous assurer de mettre ces résolveurs en dernier dans vos commandes. Je pense que la vue Tuiles en est un.

Edit: whoops ... oui, l'autre affiche est correcte, ces deux résolveurs feront "toujours la correspondance", vous ne pouvez donc pas les utiliser tous les deux dans une chaîne. Une autre solution consisterait à essayer d’étendre TilesView pour faire un simple rendu JSP s’il ne parvient pas à trouver une vue en mosaïque configurée.

Oui, vous pouvez utiliser n'importe quel nombre de résolveurs de vues dans votre projet.

Vous pouvez donc utiliser à la fois les "mosaïques de vues" et "les résolveurs de vues internes" dans le même projet. .

vous devez configurer un ContentNegotiatedViewResolver. .

et donnez une valeur à l'ordre dans vos résolveurs de vues.

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

comme j’ai donné aux tuiles la résolution 2 et internalviewresolver 3. .Il va d'abord vérifier les définitions de tuiles si aucune vue n'est trouvée dans les tuiles, elle sera vérifiée dans InternaiViewResolver

voici quelques configurations qui fonctionnent pour moi.

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

J'ai résolu ce problème en ajoutant simplement la définition des tuiles pour la présentation de Plain JSP, comme ceci:

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

Ensuite, vous pouvez simplement utiliser cette mise en page comme modèle pour inclure vos fichiers JSP simples.

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

Et le fichier de modèle de mise en page:

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top