tutorial mvc example java spring jsp spring-mvc tiles

java - mvc - Accediendo Spring Beans desde una vista de Tiles(JSP)



spring mvc menu navigation example (3)

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

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>

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

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); } }

Configuración de la 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, eche un vistazo a TilesExposingBeansView.renderMergedOutputModel. He hecho algunas pruebas, pero tal vez es necesario hacer mucho más.


¿Ha intentado usar 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>


A partir de la primavera 3.0 ahora hay un TilesViewResolver .

Subclase de conveniencia de UrlBasedViewResolver que admite TilesView (es decir, definiciones de Tiles) y sus subclases personalizadas.

La clase de vista para todas las vistas generadas por este resolutor puede especificarse a través de la propiedad "viewClass". Ver javadoc de UrlBasedViewResolver para más detalles.

Nota: Al encadenar ViewResolvers, un TilesViewResolver verificará la existencia de los recursos de plantilla especificados y solo devolverá un objeto de Vista que no sea nulo si se encontró la plantilla.

Desde: 3.0 Autor: Juergen Hoeller


Como se ha dado cuenta, esta funcionalidad es parte de InternalResourceViewResolver y InternalResourceView , mientras que las cosas de Tiles se heredan directamente de UrlBasedViewResolver y AbstractUrlBasedView , por lo que no puede hacer uso de ella.

Mirando el código, no hay razón para que esto no se haya podido colocar en AbstractUrlBasedView . La magia sucede en InternalResourceView.getRequestToExpose , y se ve perfectamente aplicable también a AbstractUrlBasedView .

En el corto plazo, sugiero subclasificar UrlBasedViewResolver y TilesView , copiando el material getRequestToExpose de InternalResourceView . A más largo plazo, lo invito a presentar un problema con SpringSource pidiéndoles que muevan esta funcionalidad hacia la jerarquía de clases a AbstractUrlBasedView , para que esté más disponible.