2010-01-15 24 views
12

En algunos frameworks MVC, puede llamar a la acción del controlador desde la vista si desea ejecutar algún código y visualizar parcialmente. No estoy seguro de cuál es la forma correcta de hacerlo en Spring MVCAcceso a los beans Spring MVC DI de jsp

Quiero tener un conjunto de plantillas JSP. Algunos de ellos serán diseños de página, algunos de ellos serán pequeños componentes como paginador, cuadro de inicio de sesión, menú, nube de etiquetas, etc. etc. Cada uno de estos componentes necesita algunos beans o acción de controlador para establecer algunos datos en ViewAndModel para que la vista pueda usarlo .

El problema es que no quiero configurar todos estos objetos en cada llamada. Mi controlador de registro solo se preocupa por el procesamiento de registro. Entonces, ¿cómo lo hago bien? ¿Cómo puedo llamar beans o controladores DI desde la vista para preparar vistas parciales? ¿O debería crear algunas asignaciones? ¿O estoy abordando el problema desde un ángulo totalmente equivocado?

Respuesta

37

Spring-MVC puede exponer los beans del contexto de la aplicación a la capa de visualización, si eso es lo que desea hacer.

Por ejemplo, el InternalResourceViewResolver puede ser instruido para exponer cada grano en el contexto, o solo los especificados. Eche un vistazo a las propiedades exposeContextBeansAsAttributes y exposedContextBeanNames.

Por ejemplo, supongamos que desea exponer los beans beanA y beanB a sus JSP. Se podría declarar la vista de resolución en su contexto así:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="exposedContextBeanNames"> 
     <list> 
     <value>beanA</value> 
     <value>beanB</value> 
     </list> 
    </property> 
</bean> 

Como alternativa, simplemente exponga cada grano:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="exposeContextBeansAsAttributes" value="true"/> 
</bean> 

Si es o no es una buena idea, es otra cuestión, pero la primavera hace darle la opción.

+1

Excelente respuesta: -) Ahora una vez que expuse el controlador a jsp puedo llamarlo y obtener la instancia del menú. No estoy seguro de cómo voy a hacerlo al final, ya que puedo ver que el acoplamiento puede aumentar rápidamente, ¡pero al menos tengo una forma de hacerlo! ¡Gracias de nuevo! – Art79

0

Nunca acceda a los componentes comerciales desde las vistas jsp; algo así como sitemesh se puede usar para combinar varias vistas en una. Jsps tampoco debería invocar directamente los métodos del controlador

+0

bien, eso es lo que estoy tratando de averiguar, cómo paso las cosas necesarias a mis archivos de vista parcial, así que no tendría que iniciarlos todos en el mismo controlador. Mi controlador no debería tener que preocuparse por otras propiedades de ModelAndView. Lo ideal sería incluir parcial (o acción de controlador de llamada) e invocaría al controlador responsable de ello y prepararía todos los datos de beans, etc. luego se pasaría a la vista parcial y se representaría. Al menos creo que funcionaría para mí: -) – Art79

+0

Si las vistas parciales son todas parte del mismo ciclo de petición-respuesta, la vista principal puede establecer todos los datos del modelo para todas las vistas parciales (como params de solicitud, por supuesto) – les2

+0

mi vista principal es home.jsp e incluye menu.jsp. ¿Qué quiere decir con "establecer todos los datos del modelo"? ¿te refieres a algo como esto? El problema que tengo aquí es que no lo hago quiero configurar la instancia $ {menu} de cada controlador que pueda tener. Me gustaría tener esto cuidado en un 'módulo' separado. Creo que tiene que haber alguna forma simple de tratar este tipo de casos de uso: -) Estoy recién de primavera y no puedo verlo: -) – Art79

5

OMI utilizar Agregar exposedContextBeanNames en la configuración de frijol ViewResolver (también hay posibilidad de utilizar el indicador global y más bien no es recomendable)

<bean id="viewResolver" 
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
<property name="exposedContextBeanNames"> 
<list> 
    <value>beanName</value> 
</list> 

uso en su JSP

${beanName.property} 
1

Una parte crítica del uso de InternalResourceViewResolver parece ser que Spring debe estar involucrado en el flujo de código cuando la página jsp está siendo procesado. Si está accediendo directamente a la página jsp o ignorando cualquier acción basada en Spring (por ejemplo, reenviando internamente a una página jsp debido a la configuración de inicio de sesión en web.xml), eso no funcionará.

Sin embargo, es posible configurar su aplicación para que ciertos beans sean accesibles a cualquier cosa que pueda llegar al ServletContext (también conocido como applicationScope) a través del usando la clase ServletContextAttributeExporter.

En la configuración de la primavera, añadir:

<bean id="mybean" .../> 
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter"> 
    <property name="attributes"> 
     <map> 
      <entry key="attrname" value-ref="mybean"/> 
     </map> 
    </property> 
</bean> 

Luego, en una página JSP se podía acceder a esa frijol con:

${applicationScope.attrname} 

o si usted sabe que no tiene una "attrname "atributo en un ámbito más específico, simplemente:

${attrname} 

Obviamente, esto no será capaz de hacer referencia a la solicitud o s ession scope beans, pero si necesita acceso a un bean singleton, funciona de maravilla.

2

Puede utilizar spring:eval etiqueta:

... 
<spring:eval expression="@properties.getProperty('myProp')" var="myProp" /> 
${myProp} 
... 

Dónde @properties es un nombre de frijol de que las propiedades de Contexto primavera. Tenga en cuenta que este enfoque no usa exposedContextBeanNames, por lo que se puede usar con Vistas de mosaicos, por ejemplo (TilesViewResolver no tiene esa propiedad).

Cuestiones relacionadas