Domanda

Sto lavorando ad un'app Web in cui ho la maggior parte delle mie pagine che usano i riquadri apache (2.1.2), ma alcuni di essi devono essere semplicemente jsps.

Sto riscontrando un problema in quanto sia un InternalResourceViewResolver che un UrlBasedViewResolver cercheranno di risolvere la vista in ogni caso, quindi, indipendentemente dall'ordinamento che uso, avrà esito negativo sulle semplici pagine JSP o sulle pagine dei riquadri.

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, devo essere in grado di visualizzare stati come 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 io riesca a renderle per il rendering di definizioni di tessere e jsps semplici?

È stato utile?

Soluzione

Come dici tu, non puoi metterli insieme. Il javadoc per entrambi afferma chiaramente che devono essere entrambi alla fine della catena di risoluzione.

Suggerisco che se hai davvero bisogno di usare questi togather, allora scrivi una semplice implementazione personalizzata di ViewResolver che prende il nome della vista e decidi quale dei tuoi due "reali" visualizzare i resolver a cui delegare. Ciò presuppone che sia possibile stabilire quale resolver chiamare in base al nome della vista.


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

Dovresti implementare il metodo isTilesView per decidere a quale resolver delegare.

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

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

Altri suggerimenti

Ho appena risolto lo stesso problema suddividendo 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 il risolutore della vista Piastrelle, tests-servlet.xml contiene solo il risolutore della vista JSP e web.xml i mapping inviano richieste al servlet corretto in base all'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>

Sembra che tu sia sulla buona strada, ma la cosa da tenere a mente è che alcuni risolutori della vista si comportano come se avessero sempre risolto la vista. È necessario assicurarsi di inserire tali resolver nell'ordine. Credo che la vista Tiles sia una di queste.

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

Sì, è possibile utilizzare qualsiasi numero di risolutore di viste nel proprio progetto.

Quindi puoi usare sia 'riquadri View resolver' che 'Internal view resolver' nello stesso progetto. .

devi configurare un ContentNegotiatedViewResolver. .

e dai il valore dell'ordine ai risolutori della tua vista.

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

come ho dato ai riquadri view resolver 2 e internalviewresolver 3.. Per prima cosa controllerà le definizioni dei riquadri se una vista non viene trovata nei riquadri verrà verificata in InternaiViewResolver

ecco alcune configurazioni che funzionano per me.

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

Ho risolto questo problema semplicemente aggiungendo la definizione di riquadri per il layout di jsp semplice, come questo:

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

Quindi puoi semplicemente usare questo layout come modello per includere i tuoi semplici file jsp.

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

E file modello layout:

<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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top