2010-01-15 74 views
12

在一些MVC框架中,如果您希望执行一些代码并渲染一些局部视图,您可以从视图中调用控制器操作。我不确定在Spring MVC中做什么是正确的方法从jsp访问Spring MVC DI bean

我想拥有一组JSP模板。其中一些将是页面布局,其中一些将是小组件,如paginator,登录框,菜单,标签云等等等等。这些组件中的每一个都需要一些bean或控制器动作来将一些数据设置到ViewAndModel中,以便视图可以使用它。

问题是我不想在每次调用中设置所有这些对象。我的注册管理员只关心注册处理。那么现在我该如何做对了?如何从视图调用DI bean或控制器来准备部分视图?或者我应该创建一些映射?还是我从完全错误的角度来处理问题?

回答

37

Spring-MVC可以将应用程序上下文的bean暴露给视图层,如果这是你想要做的。

例如,可以指示InternalResourceViewResolver公开上下文中的每个bean或仅指定的bean。看看exposeContextBeansAsAttributesexposedContextBeanNames属性。

例如,假设您想将豆类beanAbeanB展示给您的JSP。你会在你的情况下这样声明的视图解析:

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

或者,只是揭露每个bean:

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

不管这是一个好主意是另一个问题,但春天确实给你选项。在视图解析器的bean的配置

+1

优秀的回答: - ) 现在,一旦我将控制器暴露给jsp,我实际上可以调用它并获取菜单实例。我不知道我该怎么做到底,因为我可以看到耦合可以快速增加,但至少我有办法做到这一点! 再次感谢! – Art79 2010-01-15 14:48:18

0

永远不要从jsp视图访问业务组件;像sitemesh这样的东西可以用来将多个视图合并为一个。 jsps也不应该直接调用控制器方法

+0

很好,这就是我试图找出,我如何将必要的事情传递给我的部分视图文件,所以我不必在同一个控制器中启动它们。我的控制器不应该关心其他ModelAndView属性。 理想情况下,我会包括部分(或调用控制器动作),它会调用负责它的控制器并准备来自bean等的所有数据,然后它将被传递到局部视图并呈现。 至少我认为这对我很有用: - ) – Art79 2010-01-15 14:22:51

+0

如果部分视图都是同一个请求 - 响应cyhcle的一部分,那么主视图可以设置所有部分视图的所有模型数据(当然,请求参数) – les2 2010-01-15 14:26:36

+0

我的主视图是home.jsp,它包含menu.jsp。 “设置所有模型数据”是什么意思? 你的意思是这样的吗? 我在这里的问题是我没有想从每个我可以拥有的控制器设置$ {menu}实例。我希望在一个单独的“模块”中处理这个问题。 我认为必须有一些简单的方法来处理这种用例: - )即时只是新鲜的春天,不能看到它: - ) – Art79 2010-01-15 14:33:26

5

IMO 添加使用exposedContextBeanNames(也有可能使用全局标志,它是相当不推荐)

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

使用在你的JSP

${beanName.property} 
1

使用InternalResourceViewResolver的关键部分似乎是Spring需要参与代码流,当jsp页面正在处理中。 如果您直接访问jsp页面或绕过任何基于Spring的操作(例如,可能由于web.xml中的登录配置而导致内部转发到jsp页面),那么这将不起作用。

但是,可以配置您的应用程序,以便某些bean可以通过 类访问ServletContext(又称applicationScope)的任何内容。

在Spring配置,添加:

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

然后,在JSP页面中,你可以访问与该豆:

${applicationScope.attrname} 

,或者如果你知道你没有一个“attrname “在更具体的范围内属性,只是:

${attrname} 

很明显,这将无法引用请求或s ession scope bean,但是如果你需要访问一个singleton bean,那么它的效果很好。

2

您可以使用spring:eval标签:

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

@properties是你性质Spring上下文中一个bean的名字。请注意,此方法不使用exposedContextBeanNames,因此它可以与Tiles Views一起使用,例如(TilesViewResolver不具有这样的propery)。