从 jsp 访问 Spring MVC DI bean
Posted
技术标签:
【中文标题】从 jsp 访问 Spring MVC DI bean【英文标题】:Accessing Spring MVC DI beans from jsp 【发布时间】:2010-01-15 14:14:55 【问题描述】:在某些 MVC 框架中,如果您希望执行某些代码并呈现某些局部视图,则可以从视图中调用控制器操作。我不确定在 Spring MVC 中正确的方法是什么
我想要一组 JSP 模板。其中一些将是页面布局,其中一些将是小组件,例如分页器、登录框、菜单、标签云等。这些组件中的每一个都需要一些 bean 或控制器操作来将一些数据设置到 ViewAndModel 中,以便视图可以使用它.
问题是我不想在每次调用中设置所有这些对象。我的注册控制器只关心注册处理。那么现在我该怎么做呢?如何从视图中调用 DI bean 或控制器来准备部分视图?或者我应该创建一些映射?还是我从完全错误的角度解决问题?
【问题讨论】:
【参考方案1】:Spring-MVC 可以将应用程序上下文的 bean 暴露给视图层,如果您希望这样做的话。
例如,InternalResourceViewResolver
可以被指示公开上下文中的每个 bean,或者只是指定的。查看exposeContextBeansAsAttributes 和exposedContextBeanNames 属性。
例如,假设您想将 bean beanA
和 beanB
公开给您的 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>
这是否是一个好主意是另一个问题,但 Spring 确实为您提供了选择。
【讨论】:
优秀答案 :-) 现在,一旦我将控制器暴露给 jsp,我就可以真正调用它并获取菜单实例。我不确定最后我将如何做,因为我可以看到耦合可以快速增加,但至少我有办法做到!再次感谢!【参考方案2】:国际海事组织 在 viewResolver bean 配置中添加使用暴露的ContextBeanNames(也有可能使用全局标志,不推荐)
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposedContextBeanNames">
<list>
<value>beanName</value>
</list>
在你的 JSP 中使用
$beanName.property
【讨论】:
【参考方案3】:使用 InternalResourceViewResolver 的一个关键部分似乎是在处理 jsp 页面时需要将 Spring 参与到代码流中。 如果您直接访问 jsp 页面或以其他方式绕过任何基于 Spring 的操作(例如,由于 web.xml 中的登录配置,可能通过内部转发到 jsp 页面),那么这将不起作用。
但是,可以配置您的应用程序,以便某些 bean 可以访问任何可以通过以下方式访问 ServletContext(又名 applicationScope)的 ServletContextAttributeExporter 类的使用。
在你的 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 页面中,您可以通过以下方式访问该 bean:
$applicationScope.attrname
或者如果您知道在更具体的范围内没有“attrname”属性,只需:
$attrname
显然这将无法引用请求或会话范围的 bean,但如果您需要访问单例 bean,那么它会很好用。
【讨论】:
【参考方案4】:你可以使用spring:eval
标签:
...
<spring:eval expression="@properties.getProperty('myProp')" var="myProp" />
$myProp
...
@properties
是 Spring 上下文中属性的 bean 名称。请注意,这种方法不使用exposedContextBeanNames
,因此它可以与Tiles Views 一起使用,例如(TilesViewResolver
没有这样的属性)。
【讨论】:
【参考方案5】:永远不要从 jsp 视图访问业务组件;像 sitemesh 这样的东西可以用来将多个视图合并为一个。 Jsps 也不应该直接调用控制器方法
【讨论】:
很好,这就是我想要弄清楚的,我如何将必要的东西传递给我的部分视图文件,这样我就不必在同一个控制器中启动它们。我的控制器不必关心其他 ModelAndView 属性。理想情况下,我将包括部分(或调用控制器操作),它会调用负责它的控制器并准备来自 bean 等的所有数据。然后它将被传递到部分视图并呈现。至少我认为这对我有用:-) 如果部分视图都是同一个请求-响应循环的一部分,那么主视图可以为所有部分视图设置所有模型数据(当然作为请求参数) 我的主视图是 home.jsp,它包括 menu.jsp。 “设置所有模型数据”是什么意思?你的意思是这样的吗?基于注释的方法来解决 JSP 中 Spring bean 的使用问题。
Spring MVC + JSP 瓦片:
@Bean
public ViewResolver tilesViewResolver()
final UrlBasedViewResolver = new UrlBasedViewResolver();
...
viewResolver.setExposeContextBeansAsAttributes(true);
viewResolver.setExposedContextBeanNames("myBean");
return viewResolver;
在我的 .jsp 中:
<c:set var="myBeanData" scope="request" value="$myBean.myMethod()"/>
<a id="id" href="$myBeanData">Link</a>
【讨论】:
以上是关于从 jsp 访问 Spring MVC DI bean的主要内容,如果未能解决你的问题,请参考以下文章
Spting +Spring MVC+spring date jsp +hibernate+jq