19

在 Spring MVC 中,我可以使用 JstlView 的暴露上下文BeanNames(或暴露上下文BeansAsAttributes)在 JSP 中访问我的 bean。例如,然后,我可以在我的 JSP 中编写 (${properties.myProperty)。但是当同一个 JSP 是瓦片视图的一部分时,这些属性就无法访问了。是否可以正确配置 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 的解决方案。

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:

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。我做了一些测试,但也许有必要做更多。

4

3 回答 3

13

您是否尝试过在 xml 配置文件中使用ServletContextAttributeExporter ?

<bean
    class="org.springframework.web.context.support.ServletContextAttributeExporter">
    <property name="attributes">
        <map>
            <entry key="<bean key here>">
                <ref bean="<bean name here" />
            </entry>
        </map>
    </property>
</bean>
于 2013-07-08T14:40:49.910 回答
12

正如你所注意到的,这个功能是 and 的一部分InternalResourceViewResolverInternalResourceView而 Tiles 的东西直接继承自UrlBasedViewResolverand AbstractUrlBasedView,所以你不能使用它。

查看代码,没有理由不能将这些东西放入AbstractUrlBasedView. 魔法发生在 中InternalResourceView.getRequestToExpose,它看起来AbstractUrlBasedView也完全适用于。

在短期内,我建议子类化UrlBasedViewResolverTilesViewgetRequestToExposeInternalResourceView. 从长远来看,我鼓励您向SpringSource提出问题,要求他们将此功能向上移动到类层次结构AbstractUrlBasedView中,使其更广泛地可用。

于 2010-05-17T11:14:17.150 回答
1

从 Spring 3.0 开始,现在有一个TilesViewResolver

UrlBasedViewResolver 的便利子类,支持 TilesView(即 Tiles 定义)及其自定义子类。

此解析器生成的所有视图的视图类可以通过“viewClass”属性指定。有关详细信息,请参阅 UrlBasedViewResolver 的 javadoc。

注意:链接 ViewResolver 时,TilesViewResolver 将检查指定模板资源是否存在,如果实际找到模板,则仅返回非空 View 对象。

自:3.0 作者:Juergen Hoeller

于 2012-03-18T02:56:25.230 回答