如何使OpenSessionInViewFilter排除静态资源

时间:2012-04-26 10:01:43

标签: java hibernate web.xml open-session-in-view

我为我的MVC webapp实现了OpenSessionInViewFilter,它几乎完美无缺。唯一的问题是它还为网络服务器请求的每个图像,js,css等创建一个会话。这我不想要。

我使用struts2,spring和hibernate,这是我的web.xml

<filter>
    <filter-name>lazyLoadingFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>lazyLoadingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

因为我正在映射url-pattern / *它还需要所有图像等。 我尝试将其设置为* .jsp和* .action,但之后我再次获得了lazyloading-exceptions ... 我该怎么办?我现在一直在寻找5个小时的答案,而且我的头脑中有点疯狂。

我需要做的就是使这个过滤器IGNORE所有的静态资源。而已!而对于其他一切,它可以运行。这听起来很简单,但我真的很烦我,我无法弄清楚如何。

任何帮助都会受到极大的关注。

我是否需要扩展过滤器以编写我自己的过滤器并在其中排除?如果是这样。怎么样?

编辑: 好像我可以在过滤器链的顶部为我的静态文件设置过滤器映射。然后将它们发送到“ByPassFilter”,从而绕过这些静态资源的过滤链。这是要走的路吗?

谢谢你们!

5 个答案:

答案 0 :(得分:1)

这种情况下的一般做法是将Apache Web服务器与应用程序服务器(Tomcat / JBoss)结合使用mod_jk module.

Here is link描述了如何使用这种组合。 (Another link

使用此配置的主要优点是

  1. Apache Web服务器可以提供静态内容。
  2. 动态内容请求(如* .jsp,* .action等)被委托给tomcat。
  3. 对于静态内容,可能还有其他有用的模块,如c ontent compression,因此可以缩短响应时间。
  4. 它比app服务器提供服务的场景更安全。
  5. 我知道这可能不是您正在寻找的解决方案,我建议这是一个普遍的做法。

答案 1 :(得分:0)

考虑到你有一个Bypassfilter的实现,如果你在前面有这样的过滤器,那么一旦你跳过过滤器链中的下一个过滤器,那么基本上链中的其余过滤器也会被跳过(没有&# 39;在大多数情况下,这似乎是一件令人满意的事情)。此外,请求的过滤器调用类似于

  

Filter1 - &gt; Filter2 - &gt; Struts Action / BL - &gt;过滤器2 - &gt;过滤器1

因此,在struts操作中处理请求后,OpenSessionInViewFilter将启动(可以通过在web.xml中的视图过滤器中打开会话后放置另一个旁路过滤器来避免)。但总的来说,我总是不希望跳过整个过滤器链来跳过单个过滤器。

我还没有遇到过跳过OpenSessionInViewFilter的需要,但是如果我不得不这样做,那么我将有一个过滤器扩展OpenSessionInViewFilter 过滤器而不是Bypassfilter从处理中跳过静态资源。

答案 2 :(得分:0)

仅包括您需要的模式元素。

这样的事情:

<filter-mapping>
    <filter-name>lazyLoadingFilter</filter-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>/profile/edit</url-pattern>
    <url-pattern>/cars/*</url-pattern>
</filter-mapping>

答案 3 :(得分:0)

以防有人需要扩展OpenSessionInViewFilter的解决方案。 它可以防止为预定义的静态资源创建Hibernate会话。

/**
 * Skips OpenSessionInViewFilter logic for static resources
 */
public class NonStaticOpenSessionInViewFilter extends OpenSessionInViewFilter {

    static final Pattern STATIC_RESOURCES = Pattern.compile("(^/js/.*)|(^/css/.*)|(^/img/.*)|(^/fonts/.*)|(/favicon.ico)");

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String path = request.getServletPath();
        if (STATIC_RESOURCES.matcher(path).matches()) {
            filterChain.doFilter(request, response);
        } else {
            super.doFilterInternal(request, response, filterChain);
        }
    }

}

基本上Spring应该为excludePatterns提供OpenSessionInViewFilter之类的属性。

答案 4 :(得分:-1)

我完全同意@Santosh的回答。

OpenSessionInViewFilter创建资源并将其添加到ThreadLocal对象,如果从未使用会话,则会话永远不会实际创建,这也意味着不使用数据库连接请求。 (这可能是你问题的答案)。

如果您仍需要控制事物,则可以始终创建另一个扩展OpenSessionInViewFilter的过滤器,并根据所调用的资源执行getSession方法。