【问题标题】:Accessing Spring beans from a Tiles view (JSP)从 Tiles 视图 (JSP) 访问 Spring bean
【发布时间】:2011-02-20 08:42:04
【问题描述】:

在 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。我做了一些测试,但可能需要做更多的测试。

【问题讨论】:

  • 你在谷歌上搜索过 Spring tile 集成吗?
  • 是的,我用谷歌搜索过。我在以前的版本中遇到了一些问题,但现在一切正常,除了这个问题。我搜索了它,但我什么也没找到:(
  • 伙计,spring 和 apache 必须为此给你开张支票;)干得好

标签: java spring jsp spring-mvc tiles


【解决方案1】:

正如您所注意到的,此功能是 InternalResourceViewResolverInternalResourceView 的一部分,而 Tiles 的东西直接继承自 UrlBasedViewResolverAbstractUrlBasedView,因此您无法使用它。

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

在短期内,我建议继承UrlBasedViewResolverTilesView,从InternalResourceView 复制getRequestToExpose 的东西。从长远来看,我鼓励您向SpringSource 提出问题,要求他们将此功能在类层次结构中向上移动到AbstractUrlBasedView,使其更广泛地可用。

【讨论】:

  • 我尝试过类似的方法,但它不起作用。我已经继承了 JstlView,覆盖了 initServletContext、checkResource 和 renderMergedOutputModel。我现在就试试你的想法。
  • @Sinuhe: JstlView 不会与 Tiles 兼容,机制根本不同。
  • 好吧,您的解决方案奏效了!当我这样做时,我注意到我以前的想法是不正确的。在向 SpringSource 提交问题之前,我已经尝试了更多。谢谢!
  • @skaffman 您对“ServletContextAttributeExporter”有何看法?我们不应该使用 'ServletContextAttributeExporter' 而不是扩展 UrlBasedViewResolver 的功能吗?
【解决方案2】:

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

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

此解析器生成的所有视图的视图类可以是 通过“viewClass”属性指定。请参阅 UrlBasedViewResolver 的 详情请参考 javadoc。

注意:链接 ViewResolver 时,TilesViewResolver 将检查 指定模板资源存在且只返回一个 如果实际找到模板,则为非 null View 对象。

因为: 3.0 作者:于尔根·霍勒

【讨论】:

  • TilesViewResolver 不能解决问题,因为它是 UrlBasedViewResolver 的子类,但没有添加暴露的ContextBeanNames 属性。原始帖子和接受的答案仍然是去 AFAIK 的最佳方式。
【解决方案3】:

你试过在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>

【讨论】:

  • 我使用这个是因为它更容易实现。
  • 当然这是添加会话 bean 的更优雅和不显眼的方法!我正要扩展 Spring Classes,您的解决方案节省了我几天的工作!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 2017-03-01
相关资源
最近更新 更多