Pergunta

Eu estou trabalhando em uma aplicação web, onde eu tenho a maioria das minhas páginas que fazem uso do Apache telhas (2.1.2), mas alguns deles precisam ser apenas jsps simples.

Eu estou tendo um problema em que tanto um InternalResourceViewResolver e uma UrlBasedViewResolver vai tentar resolver a vista não importa o que, de modo que não importa qual ordenando que eu uso, ele quer deixar nas páginas JSP simples, ou nas páginas de telhas .

Aqui está o 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>

Para tornar mais claro o que estou tentando fazer, eu preciso ser capaz de ter visão afirma assim:

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

Alguém sabe como configurar as coisas para que eu possa obtê-lo para tornar definições telhas e jsps simples?

Foi útil?

Solução

Como você disse, você não pode acorrentar-los juntos. O javadoc para ambos os estados claramente que eles devem ser os dois ao final da cadeia de resolver.

Eu sugiro que se você realmente precisa usar estes togather, então você escrever uma aplicação personalizada simples de viewResolver que leva o nome da visão, e decide qual dos seus dois "reais" vista resolvedores delegar. Isso pressupõe que você pode dizer que resolver a chamada com base no nome de exibição.


Assim que você definir uma viewResolver personalizado como este:

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

Você precisa implementar o método isTilesView para decidir qual resolvedor delegar.

Na configuração XML, defina essa nova visão resolver, e certifique-se que aparece antes os outros.

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

Outras dicas

Acabei de resolvido o mesmo problema dividindo o arquivo de configuração *-servlet.xml em dois; no meu caso a aplicação principal utiliza telhas, mas eu quero testes QUnit ser JSPs simples.

app-servlet.xml contém apenas o ponto de vista resolver Tiles, tests-servlet.xml contém apenas as vista resolver e web.xml mapeamentos JSP são despachando pedidos para o baseando servlet correta na 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>

Parece que você está no caminho certo, mas a coisa a ter em mente é que alguns resolvedores ver se comportam como se eles sempre resolvidos a vista. Você precisa ter certeza de colocar esses resolvedores última em sua ordenação. Eu acredito que a visão Tiles é um desses.

Editar: opa ... sim, o outro cartaz é correta, ambos os resolvedores vai fazer 'sempre corresponder' para que você não pode usá-los tanto em uma cadeia. Outra alterative seria tentar estender o TilesView para fazer um simples JSP tornar se não puder encontrar uma visão telha configurado.

Sim, você pode usar qualquer número de vista resolver em seu seu projeto.

Assim, você pode usar tanto 'telhas Ver resolver' 'vista resolver Interno' e no mesmo projeto. .

você tem que configurar um ContentNegotiatingViewResolver. .

e valor da ordem de dar na sua opinião resolvedores.

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

como se eu tivesse dado telhas ver resolvedor 2 e internalviewresolver 3. .Ele irá verificar primeiro nas definições telhas se um ponto de vista não é encontrado em telhas que serão verificados em InternaiViewResolver

aqui é algumas configurações que funciona para mim.

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

Eu resolvi esse problema simplesmente adicionando definição telhas para o layout do jsp simples, assim:

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

Então você só pode usar esse layout como modelo para a inclusão de arquivos jsp sua simples.

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

E arquivo de modelo de 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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top