从 Tiles 视图 (JSP) 访问 Spring bean [英] Accessing Spring beans from a Tiles view (JSP)
问题描述
在 Spring MVC 中,我可以在 JSP 中使用 JstlView 的暴露的ContextBeanNames(或exposeContextBeansAsAttributes)访问我的bean.例如,然后,在我的 JSP 中,我可以编写 (${properties.myProperty).但是,当同一个 JSP 是磁贴视图的一部分时,这些属性是不可访问的.是否可以正确配置 Tiles 或以其他方式访问这些属性?
In Spring MVC I can access my beans in JSP using JstlView's exposedContextBeanNames (or exposeContextBeansAsAttributes). For example, then, in my JSP I can write (${properties.myProperty). But when the same JSP is a part of a tiles view, these properties aren't accessible. Is possible to configure Tiles properly or access these properties in another way?
我使用的是 Spring MVC 3.0.2 和 Tiles 2.2.1.这是我的一些配置:
I'm using Spring MVC 3.0.2 and Tiles 2.2.1. Here's a bit of my configuration:
<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>
我已经实施了 Skaffman 的解决方案.
I've implemented Skaffman's solution.
TilesExposingBeansViewResolver.java:
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:
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);
}
}
弹簧配置:
<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>
如果您有问题,请查看 TilesExposingBeansView.renderMergedOutputModel.我已经做了一些测试,但也许有必要做更多的测试.
If you have some problem, take a look at TilesExposingBeansView.renderMergedOutputModel. I've made some tests, but maybe it's necessary to make a lot more.
推荐答案
正如你所注意到的,这个功能是 InternalResourceViewResolver
和 InternalResourceView
的一部分,而 Tiles 的东西直接从UrlBasedViewResolver
和AbstractUrlBasedView
继承,所以你不能使用它.
As you've noticed, this functionality is part of InternalResourceViewResolver
and InternalResourceView
, whereas the Tiles stuff inherits directly from UrlBasedViewResolver
and AbstractUrlBasedView
, so you can't make use of it.
看代码,没有理由不能将这些东西放入AbstractUrlBasedView
.神奇发生在 InternalResourceView.getRequestToExpose
中,它看起来也完全适用于 AbstractUrlBasedView
.
Looking at the code, there's no reason why this stuff couldn't have been put into AbstractUrlBasedView
. The magic happens in InternalResourceView.getRequestToExpose
, and it looks perfectly applicable to AbstractUrlBasedView
too.
在短期内,我建议子类化UrlBasedViewResolver
和TilesView
,从InternalResourceView
复制getRequestToExpose
内容.从长远来看,我鼓励您向 SpringSource 提出问题,要求他们将此功能向上移动到类层次结构AbstractUrlBasedView
,使其更广泛可用.
In the short term, I suggest subclassing UrlBasedViewResolver
and TilesView
, copying the getRequestToExpose
stuff from InternalResourceView
. In the longer term, I encourage you to file a issue with SpringSource asking them to move this functionality up the class hierarchy into AbstractUrlBasedView
, making it more widely available.
这篇关于从 Tiles 视图 (JSP) 访问 Spring bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!