在交叉上下文请求转发中找不到当前线程的会话

时间:2014-11-09 23:42:42

标签: java hibernate spring-mvc servlets

我在同一容器中运行了两个Web servlet(Servlet-A& Servlet-B)。 Servlet-A是无法访问数据库的Web应用程序。它有一个过滤器,可以将某些请求转发给Servlet-B。 Servlet-B是一个Spring / Hibernate应用程序,可以访问DB(使用Hibernate)。

当Servlet-A将请求转发给Servlet-B中的控制器时,后者无法为该请求创建Hibernate会话,这给了我错误:

Caused by: org.hibernate.HibernateException: No Session found for current thread
12:04:29,802 ERROR [STDERR]     at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
12:04:29,803 ERROR [STDERR]     at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:990)

Servlet-B无法识别转发请求的根上下文,因此无法授予其访问权限。

以下是我在Servlet-A中所做的事情 (1)过滤器设置

   <filter>
        <filter-name>CandidateProxyFilter</filter-name>
        <filter-class>com.candidate.filter.CandidateProxyFilter</filter-class>                      
    </filter>
    <filter-mapping>
        <filter-name>CandidateProxyFilter</filter-name>
        <url-pattern>*.html</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

(2)Servlet-B过滤代码:

public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException,
                ServletException {
        final RequestDispatcher proxyDispatcher = createProxyDispatcher(request);
        proxyDispatcher.forward(request, response);
}

此处Servlet-B上的相关控制器代码:

@RequestMapping(method = RequestMethod.GET)
public String invokeView() {

    final Candidate candidate = candidateService.getCandidate(); // Crash !!!
...
}

CandidateService使用Hibernate会话访问了数据库,但是对于从Servlet-A转发的请求,它会抛出上述错误。 对于从Servlet-B上下文触发的请求,这很好。 我只是想了解发生了什么以及如何解决问题?

1 个答案:

答案 0 :(得分:0)

我修好了! 结果表明OpenSessionInViewFilterServlet-B的配置默认忽略了所有FORWARD请求类型:

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

我所要做的就是将以下内容添加到过滤器中:

<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>        

最终设置如下:

 <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>
            org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>        
    </filter-mapping>