2

我已经为我的 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,但后来我又得到了延迟加载异常......我应该怎么做? 我已经寻找答案 5 个小时了,我的脑海里有点疯狂。

我需要做的就是让这个过滤器忽略所有静态资源。就是这样!对于其他一切它可以运行。听起来很简单,但真的很烦我,我不知道怎么做。

任何帮助将不胜感激。

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

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

多谢你们!

4

5 回答 5

1

这种情况下的一般做法是使用 Apache Web 服务器与带有mod_jk 模块的应用程序服务器 (Tomcat/JBoss) 的组合。

这是描述如何使用此组合的链接。(另一个链接

使用此配置的主要优点是

  1. 静态内容可以由 Apache Web 服务器提供。
  2. 动态内容请求(如 *.jsp、*.action 等)被委托给 tomcat。
  3. 可能还有其他有用的模块,例如静态内容的内容压缩,从而提高响应时间。
  4. 它比应用服务器为所有内容提供服务的场景更安全。

我知道这可能不是您正在寻找的解决方案,我建议这样做,因为这是一种普遍做法。

于 2012-04-26T10:20:48.963 回答
0

就您的 Bypassfilter 实现而言,如果您在前面有这样一个过滤器,那么一旦您跳过过滤器链中的下一个过滤器,那么基本上链中的其余过滤器也将被跳过(这似乎没有在大多数情况下是一件可取的事情)。此外,请求的过滤器调用表现得像

Filter1 -> Filter2 --> Struts Action/BL --> 过滤器 2 --> 过滤器 1

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

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

于 2012-04-26T11:12:16.110 回答
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>
于 2016-01-28T15:21:34.197 回答
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 应该提供一些属性,例如excludePatternsfor OpenSessionInViewFilter

于 2016-06-07T21:39:45.097 回答
-1

我完全同意@Santosh 的回答。

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

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

于 2012-04-26T10:51:13.527 回答