如何在Sitemesh装饰器中获取模型属性或Spring的Bean?

8

我正在使用Spring 3和sitemesh。我想在sitemesh中定义的装饰器页面中引用spring上下文bean。

问题在于SiteMesh过滤器在Spring上下文之外工作,因此sitemesh装饰器jsp页面上的请求对象是原生HttpServletRequest,而不是包装器,无法访问上下文等有用函数。

是否有一种方法可以配置Spring和Sitemesh来在装饰器页面中访问Spring上下文?


如果您包含一些配置,特别是视图解析器,也许有人可以更轻松地帮助您。如果您禁用Sitemesh过滤器,那么您的公开bean是否可访问?我从未使用过Sitemesh,但我曾经在Tiles中遇到过类似的问题:https://dev59.com/eXE85IYBdhLWcg3wSxgv - sinuhepop
3
他不应该需要包含任何那些内容——问题不是基于配置,而是因为SiteMesh在Spring上下文之外装饰页面。 - walnutmon
4个回答

3

我曾经也遇到过同样的问题,并通过使用一个过滤器来解决了我的问题。我创建了一个环境过滤器,可以用于设置所有请求的环境数据。在过滤器中自动装配你需要访问的bean。

@Component
public class EnvironmentFilter extends OncePerRequestFilter {

    @Autowired
    Object bean;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        request.setAttribute("bean", bean); // add bean or just specific properties of bean.

        filterChain.doFilter(request, response);

    }

}

在web.xml中配置过滤器时,请确保使用与Sitemesh过滤器相同的模式进行过滤器映射。

<filter>
    <filter-name>environmentFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>environmentFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

你的过滤器设置的属性现在可以从装饰器页面中获取。

0

从创建一个单例开始,您可以选择任何您喜欢的对象类型,我只是设置了一个字符串,但任何类都可以:

public class MySiteEnvironment {

    private String someConfigurationParameter;

    public String getSomeConfigurationParameter() {
        return someConfigurationParameter;
    }

    public void setSomeConfigurationParameter(String someConfigurationParameter) {
        this.someConfigurationParameter = someConfigurationParameter;
    }

    /* SINGLETON */
    private static final MySiteEnvironment INSTANCE = new MySiteEnvironment();

    private MySiteEnvironment() {
    }

    public static MySiteEnvironment getInstance() {
        return INSTANCE;
    }
}

接下来您需要注入该值:

<bean id="mySiteEnvironment" class="MySiteEnvironment" factory-method="getInstance">
        <property name="someConfigurationParameter" value="myValueOrBean"/>
    </bean>

最后,您可以通过以下方式访问它:

<%@ page import="MySiteEnvironment" %>
<% pageContext.setAttribute("env", MySiteEnvironment.getInstance()); %> 

现在您可以使用表达式语言来访问环境。

0

我通过重新实现Sitemesh过滤器解决了这个问题:

@Component
class SitemeshSpringFilter extends PageFilter implements ApplicationContextAware {
    ApplicationContext applicationContext;

    @Override
    public void doFilter(ServletRequest rq, ServletResponse rs,
            FilterChain chain) throws IOException, ServletException {
        def newRq = new ContextExposingHttpServletRequest(
                rq, getApplicationContext(), null);

        super.doFilter(newRq, rs, chain);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    throws BeansException {
        this.applicationContext = applicationContext;
    }
}

在 web.xml 中声明此过滤器:
<filter>
    <filter-name>sitemeshSpringFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>sitemeshSpringFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

现在,Sitemesh过滤器将使用ContextExposingHttpServletRequest而不是普通请求。


0

我不知道如何做你所要求的事情,但也有另一种选择。您可以在控制器方法参数中声明HttpServletRequest。如果需要将模型对象可用于Sitemesh,请将它们放在请求上。无论支持上下文是servlet请求还是Spring MVC模型,JSP代码看起来完全相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接