在Spring MVC中,我可以使用JstlView的posedContextBeanNames(或暴露ContextBeansAsAttributes)在JSP中访问我的bean。例如,然后,在我的JSP中,我可以编写($ {properties.myProperty)。但是,当相同的JSP是tile视图的一部分时,将无法访问这些属性。是否可以正确配置Tiles或以其他方式访问这些属性?
我正在使用Spring MVC 3.0.2和Tiles 2.2.1。这是我的一些配置:
<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的解决方案。
TilesExposedBeansViewResolver.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; } }
TilesExposedBeansView.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>
如果遇到问题,请查看TilesExposedBeansView.renderMergedOutputModel。我做了一些测试,但是也许有必要做更多的事情。
您已经注意到,此功能是InternalResourceViewResolver和的一部分InternalResourceView,而Tiles东西直接继承自UrlBasedViewResolver和AbstractUrlBasedView,因此您无法使用它。
InternalResourceViewResolver
InternalResourceView
UrlBasedViewResolver
AbstractUrlBasedView
查看代码,没有理由不把这些东西放进去AbstractUrlBasedView。魔术发生在中InternalResourceView.getRequestToExpose,并且看起来也完全适用AbstractUrlBasedView。
InternalResourceView.getRequestToExpose
在短期内,我建议子类化UrlBasedViewResolver并从中TilesView复制getRequestToExpose内容InternalResourceView。从长远来看,我鼓励您向SpringSource提出问题,要求他们将此功能在类层次结构中移入AbstractUrlBasedView,使其更广泛地可用。
TilesView
getRequestToExpose