2010-01-15 9 views
12

Dans certains frameworks MVC, vous pouvez appeler l'action du contrôleur de la vue si vous souhaitez exécuter du code et de rendre une vue partielle. Je ne sais pas quelle est la bonne façon de le faire au printemps MVCharicots Spring MVC Accès DI de jsp

Je veux avoir un ensemble de modèles JSP. Certains d'entre eux seront des mises en page dont certaines seront de petits composants tels que paginateur, boîte de connexion, menu, nuage de tags etc etc Chacun de ces composants nécessite des beans ou une action du contrôleur pour placer des données dans ViewAndModel afin que la vue puisse l'utiliser .

Le problème est que je ne veux pas mettre tous ces objets dans chaque appel. Mon contrôleur de registres se soucie uniquement du traitement de l'enregistrement. Alors maintenant, comment puis-je le faire correctement? Comment appeler les beans DI ou les contrôleurs de la vue pour préparer des vues partielles? Ou devrais-je créer des mappings? Ou est-ce que j'aborde le problème sous un angle totalement faux?

Répondre

37

Spring MVC peut exposer les haricots du contexte d'application de la couche de vue, si c'est ce que vous voulez faire.

Par exemple, le InternalResourceViewResolver peut être chargé d'exposer chaque grain dans le contexte, ou tout simplement ceux spécifiés. Jetez un oeil aux propriétés exposeContextBeansAsAttributes et exposedContextBeanNames. Par exemple, disons que vous vouliez exposer les fèves beanA et beanB à vos JSP. Par exemple, disons que vous vouliez exposer les fèves beanA et beanB. Vous devrez déclarer le résolveur de vue dans votre contexte ainsi:

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

Sinon, juste exposer chaque grain:

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

Que ce soit ou non est une bonne idée est une autre question, mais le printemps ne vous donne l'option.

+1

Excellente réponse: -) Maintenant une fois que j'ai exposé le contrôleur à jsp je peux réellement l'appeler et obtenir l'instance de menu. Je ne sais pas comment je vais le faire à la fin car je peux voir que le couplage peut augmenter rapidement mais au moins j'ai un moyen de le faire! Merci encore! – Art79

0

N'accédez jamais aux composants métier à partir des vues jsp; quelque chose comme sitemesh peut être utilisé pour combiner plusieurs vues en une seule. JSPS devrait pas non plus invoquer des méthodes de commande directement

+0

Bien, c'est ce que j'essaie de comprendre, comment puis-je passer les choses nécessaires à mes fichiers de vue partielle afin que je ne devrais pas les initier tous dans le même contrôleur. Mon contrôleur ne devrait pas avoir à se préoccuper des autres propriétés ModelAndView. Idéalement, je voudrais inclure partielle (ou appeler l'action du contrôleur) et il invoquerait le contrôleur responsable et préparer toutes les données à partir de haricots etc puis il serait passé à la vue partielle et rendu. Au moins, je pense que cela fonctionnerait pour moi: -) – Art79

+0

Si les vues partielles font toutes partie du même cyhcle requête-réponse, la vue principale peut définir toutes les données du modèle pour toutes les vues partielles (comme les paramètres de requête bien sûr) – les2

+0

ma vue principale est home.jsp et elle inclut menu.jsp. Que voulez-vous dire par "définir toutes les données du modèle"? voulez-vous dire quelque chose comme ça? Le problème im avoir ici est que je ne sais pas veux mettre $ {menu} instance de chaque contrôleur que je peux avoir. Je voudrais que cela soit pris en compte dans un 'module' séparé. Je pense qu'il doit y avoir un moyen simple de traiter ce genre de cas d'utilisation: -) im juste frais au printemps et ne peux pas le voir: -) – Art79

5

OMI exposedContextBeanNames d'utilisation Ajouter dans la configuration de haricot ViewResolver (il y a aussi possibilité d'utiliser le drapeau global et il est plutôt pas recommandé)

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

utilisation dans votre JSP

${beanName.property} 
1

Une partie critique de l'utilisation de InternalResourceViewResolver semble être que Spring doit être impliqué dans le flux de code lorsque la page jsp est en cours de traitement. Si vous accédez directement à la page jsp ou si vous ignorez une action basée sur Spring (par exemple en la redirigeant en interne vers une page jsp en raison d'une configuration de connexion dans web.xml), cela ne fonctionnera pas.

Cependant, il est possible de configurer votre application pour que certains beans soient accessibles à tout ce qui peut atteindre le ServletContext (aka applicationScope) en utilisant la classe ServletContextAttributeExporter.

Dans la configuration de votre ressort, ajoutez:

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

Puis, dans une page JSP, vous pouvez accéder à ce bean avec:

${applicationScope.attrname} 

ou si vous savez que vous ne disposez pas d'un « attrname "attribut dans une portée plus spécifique, juste:

${attrname} 

De toute évidence, cela ne sera pas en mesure de faire référence à la demande ou s beans, mais si vous avez besoin d'un haricot singleton, cela fonctionne très bien.

2

Vous pouvez utiliser spring:eval tag:

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

@properties est un nom de haricot de propriétés que vous dans le contexte du printemps. Notez que cette approche n'utilise pas exposedContextBeanNames, elle peut donc être utilisée avec des vues en mosaïque, par exemple (TilesViewResolver n'a pas cette propriété).

Questions connexes