2010-05-17 20 views
19

En Spring MVC puedo acceder a mis beans en JSP utilizando exposedContextBeanNames de JstlView (o exposeContextBeansAsAttributes). Por ejemplo, entonces, en mi JSP puedo escribir ($ {properties.myProperty). Pero cuando el mismo JSP forma parte de una vista de mosaicos, estas propiedades no son accesibles. ¿Es posible configurar Tiles correctamente o acceder a estas propiedades de otra manera?Acceso a beans Spring desde una vista Tiles (JSP)

Estoy usando Spring MVC 3.0.2 y Tiles 2.2.1. Aquí hay un poco de mi configuración:

<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
    <property name="order" value="1"/> 
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" /> 
</bean> 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> 
    <property name="order" value="2"/> 
    <property name="prefix" value="/WEB-INF/views/"/> 
    <property name="suffix" value=".jsp"/> 
    <property name="exposedContextBeanNames"> 
     <list><value>properties</value></list> 
    </property> 
</bean> 

EDIT: He implementado la solución de Skaffman.

TilesExposingBeansViewResolver.java:

package es.kcsolutions.util.spring.servlet.view; 

import org.springframework.web.servlet.view.*; 

public class TilesExposingBeansViewResolver extends UrlBasedViewResolver { 

    private Boolean exposeContextBeansAsAttributes; 
    private String[] exposedContextBeanNames; 

    public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes) { 
     this.exposeContextBeansAsAttributes = exposeContextBeansAsAttributes; 
    } 

    public void setExposedContextBeanNames(String[] exposedContextBeanNames) { 
     this.exposedContextBeanNames = exposedContextBeanNames; 
    } 

    @Override 
    protected AbstractUrlBasedView buildView(String viewName) throws Exception { 
     AbstractUrlBasedView superView = super.buildView(viewName); 
     if (superView instanceof TilesExposingBeansView) { 
      TilesExposingBeansView view = (TilesExposingBeansView) superView; 
      if (this.exposeContextBeansAsAttributes != null) view.setExposeContextBeansAsAttributes(this.exposeContextBeansAsAttributes); 
      if (this.exposedContextBeanNames != null) view.setExposedContextBeanNames(this.exposedContextBeanNames); 
     } 
     return superView; 
    } 

} 

TilesExposingBeansView.java: configuración

package es.kcsolutions.util.spring.servlet.view; 

import java.util.*; 
import javax.servlet.http.*; 
import org.springframework.web.context.support.ContextExposingHttpServletRequest; 
import org.springframework.web.servlet.view.tiles2.TilesView; 

public class TilesExposingBeansView extends TilesView { 

    private boolean exposeContextBeansAsAttributes = false; 
    private Set<String> exposedContextBeanNames; 

    public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes) { 
     this.exposeContextBeansAsAttributes = exposeContextBeansAsAttributes; 
    } 

    public void setExposedContextBeanNames(String[] exposedContextBeanNames) { 
     this.exposedContextBeanNames = new HashSet<String>(Arrays.asList(exposedContextBeanNames)); 
    } 

    protected HttpServletRequest getRequestToExpose(HttpServletRequest originalRequest) { 
     if (this.exposeContextBeansAsAttributes || this.exposedContextBeanNames != null) 
     return new ContextExposingHttpServletRequest(originalRequest, getWebApplicationContext(), this.exposedContextBeanNames); 
     return originalRequest; 
    } 

    @Override 
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { 
     HttpServletRequest requestToExpose = getRequestToExpose(request); 
     exposeModelAsRequestAttributes(model, requestToExpose); 
     super.renderMergedOutputModel(model, requestToExpose, response); 
    } 

} 

primavera:

<bean id="tilesViewResolver" class="es.kcsolutions.util.spring.servlet.view.TilesExposingBeansViewResolver"> 
     <property name="order" value="1"/> 
     <property name="viewClass" value="es.kcsolutions.util.spring.servlet.view.TilesExposingBeansView"/> 
     <property name="exposedContextBeanNames"> 
      <list><value>properties</value></list> 
     </property> 
    </bean> 

Si tiene algún problema, echar un vistazo a TilesExposingBeansView.renderMergedOutputModel. Hice algunas pruebas, pero tal vez sea necesario hacer mucho más.

+0

¿hiciste google para la integración de baldosas de primavera? – Bozho

+0

Sí, busqué en Google. Tengo algunos problemas con las versiones anteriores, pero ahora todo estaba bien, excepto por este problema. Lo busqué pero no he encontrado nada :( – sinuhepop

+2

man, spring y apache deben escribirte un cheque para esto;) great job – Ricardo

Respuesta

12

Como se ha notado, esta funcionalidad es parte de InternalResourceViewResolver y InternalResourceView, mientras que el material Azulejos hereda directamente de UrlBasedViewResolver y AbstractUrlBasedView, por lo que no puede hacer uso de ella.

Mirando el código, no hay ninguna razón por la cual esta cosa no podría haberse puesto en AbstractUrlBasedView. La magia ocurre en InternalResourceView.getRequestToExpose, y parece perfectamente aplicable también a AbstractUrlBasedView.

En el corto plazo, sugieren que la subclasificación UrlBasedViewResolver y TilesView, copiar el material de getRequestToExposeInternalResourceView. A más largo plazo, lo animo a que presente un problema con SpringSource pidiéndoles que muevan esta funcionalidad a la jerarquía de clases en AbstractUrlBasedView, haciéndola más ampliamente disponible.

+0

He intentado algo similar, pero no funciona. He subclasificado JstlView, anulando initServletContext, checkResource y renderMergedOutputModel. Voy a intentar tu idea ahora. – sinuhepop

+0

@Sinuhe: 'JstlView' no va a ser compatible con Tiles, los mecanismos son fundamentalmente diferentes. – skaffman

+0

¡Bien, tu solución funcionó! Mientras lo hacía, noté que mi idea anterior no era correcta. Lo intenté un poco más antes de archivar un problema a SpringSource. ¡Gracias! – sinuhepop

1

A partir de Spring 3.0 ahora hay un TilesViewResolver.

conveniencia subclase de UrlBasedViewResolver que soporta TilesView (es decir, las definiciones azulejos) y subclases personalizados de la misma.

La clase de vista para todas las vistas generadas por este resolver puede ser especificada mediante la propiedad "viewClass". Consulte el javadoc de de UrlBasedViewResolver para obtener más detalles.

Nota: Cuando se encadenan ViewResolvers, un TilesViewResolver comprobará la existencia de los recursos especificados plantilla y sólo volver a View no nulo objeto si en realidad se encontró la plantilla.

Desde: 3.0 Autor: Juergen Holler

+1

TilesViewResolver no resuelve el problema ya que subclasifica UrlBasedViewResolver sin agregar la propiedad exposedContextBeanNames. La publicación original y la respuesta aceptada siguen siendo la mejor manera de acceder a AFAIK. – azpublic

13

¿Ha intentado utilizar ServletContextAttributeExporter en el archivo de configuración XML?

<bean 
    class="org.springframework.web.context.support.ServletContextAttributeExporter"> 
    <property name="attributes"> 
     <map> 
      <entry key="<bean key here>"> 
       <ref bean="<bean name here" /> 
      </entry> 
     </map> 
    </property> 
</bean> 
+2

Utilizo esto porque es más fácil de implementar. – msangel

+0

Ciertamente ¡Este es un método más elegante y discreto de agregar beans de sesión! ¡Estaba a punto de extender las clases de primavera, su solución me ahorró varios días de trabajo! GRACIAS ! –

+0

Esto es ** increíble. ** – user3120173

Cuestiones relacionadas