2009-06-22 7 views
17

Sto lavorando ad un'app web in cui ho la maggior parte delle mie pagine che usano apache tiles (2.1.2), ma alcune di esse devono essere semplicemente jsps.Come utilizzare più ViewResolvers in primavera?

Sto avendo un problema in quanto sia un InternalResourceViewResolver e UrlBasedViewResolver cercheremo di risolvere la vista non importa cosa, in modo che non importa quale ordinamento che uso, che sarà o non riuscire nelle pagine JSP pianura o sulle piastrelle pagine.

Ecco la configurazione:

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

Per rendere più chiaro ciò che sto cercando di fare, ho bisogno di essere in grado di avere stati di visualizzazione simile a questo:

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

Qualcuno sa come configurare le cose in modo che possa ottenerle per visualizzare le definizioni di tile e jsps semplici?

risposta

20

Come dici tu, non puoi incatenarli insieme. Il javadoc per entrambi gli stati chiaramente che entrambi devono essere alla fine della catena resolver.

Suggerisco che se si ha realmente bisogno di usare questi file, allora si scrive una semplice implementazione personalizzata di ViewResolver che prende il nome della vista e decide quale dei due risolutori di vista "reali" delegare. Ciò presuppone che sia possibile stabilire quale resolver chiamare in base al nome della vista.


così si potrebbe definire un ViewResolver personalizzato come questo:

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

Avresti bisogno di implementare il metodo isTilesView per decidere quale resolver di delegare a.

Nella configurazione XML, definire questo nuovo risolutore di viste e assicurarsi che appaia prima degli gli altri.

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

Potresti approfondire un po 'su questo? Non sono sicuro di come trasferire il controllo a un altro risolutore di viste. –

+0

Vedere la modifica per il codice di esempio – skaffman

+0

Sembra fantastico, ci proverò, grazie! Ho provato qualcosa di simile prima, ma era basato sulla restituzione di null per continuare lungo la catena, e non funzionava correttamente. –

1

Sembra che tu sia sulla strada giusta, ma la cosa da tenere a mente è che alcuni risolutori di vista si comportano come se avessero sempre risolto la vista. È necessario assicurarsi di mettere tali risolutori ultimo nel vostro ordine. Credo che la visione di Piastrelle sia una di queste.

Modifica: whoops ... sì, l'altro poster è corretto, entrambi i resolver faranno 'sempre la corrispondenza', quindi non puoi usarli entrambi in una catena. Un altro alterativo sarebbe cercare di estendere TilesView per eseguire un semplice rendering JSP se non riesce a trovare una vista tile configurata.

+0

Entrambi sempre si comportano in questo modo, che è ciò che crea il problema. –

3

Ho appena risolto lo stesso problema, dividendo il file di configurazione *-servlet.xml in due; nel mio caso l'applicazione principale usa Tiles, ma voglio che i test QUnit siano semplici JSP.

app-servlet.xml contiene solo la vista resolver Tiles, tests-servlet.xml contiene solo la vista resolver JSP e web.xml mappature sono dispacciamento richieste al servlet corretta basandosi sulla 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> 
0

Sì, è possibile utilizzare qualsiasi numero di resolver di visualizzazione nel proprio progetto.

Quindi è possibile utilizzare sia "Visualizza risolutore" sia "Risoluzione di vista interna" nello stesso progetto. .

devi configurare un ContentNegotiatingViewResolver. .

e fornire il valore dell'ordine nei resolver vista.

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

come ho dato piastrelle view resolver 2 e 3. internalviewresolver spiccatamente saranno controllate prima nel definizioni piastrelle se vista non si trova in piastrelle verrà controllato in InternaiViewResolver

ecco alcune configurazioni per me va bene.

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

ho risolto questo problema con la semplice aggiunta di definizione piastrelle per il layout di JSP pianura, in questo modo:

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

Poi basta può usare questo layout come modello per inclusi i file jsp semplici.

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

E modello di layout di file:

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