spring mvc拦截器请求范围

时间:2015-07-27 08:12:47

标签: java spring hibernate spring-mvc

我正在使用Spring 4.1.7和Hibernate 4.3.10开发一个Web应用程序。 我需要创建一个Interceptor来管理这样的事务:

public class ControllerInterceptor extends HandlerInterceptorAdapter
{

@Autowired
private SessionFactory sessionFactory;

private Session session;

@Override
public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler) throws Exception
{
    super.preHandle(request, response, handler);
    ControllerInterceptor ci = this;
    session = sessionFactory.getCurrentSession();
    //Transaction management....
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex) throws Exception
{
    //Transaction commit/rollback
    if (null != session && session.isOpen())
    {
        try
        {
            session.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

}
}

在applicationContext.xml中,我以这种方式定义了拦截器:

<mvc:interceptors>
    <bean class="com.interceptor.ControllerInterceptor" />
</mvc:interceptors> 

我的ControllerInterceptor是单例,但我在请求范围内需要它。 我试图以这种方式定义拦截器:

<mvc:interceptors>
    <bean class="com.interceptor.ControllerInterceptor" scope="request" />
</mvc:interceptors> 

但我有这个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

有任何建议吗?谢谢

1 个答案:

答案 0 :(得分:-1)

MVC拦截器不需要具有请求范围,因为它们仅针对当前请求执行。

引用HandlerInterceptor.preHandle -

的java文档
  

拦截处理程序的执行。 在HandlerMapping确定适当的处理程序对象之后调用,但在HandlerAdapter调用处理程序之前。   DispatcherServlet处理执行链中的处理程序,该处理程序由任意数量的拦截器组成,最后处理程序本身。使用此方法,每个拦截器都可以决定中止执行链,通常发送HTTP错误或编写自定义响应。

     

参数:   
请求 - 当前 HTTP请求   
响应 - 当前 HTTP响应   
处理程序 - 为执行类型和/或实例评估而选择的处理程序

此外,正如Olesksii正确指出的那样,你需要在这里避免会话/交易管理的反模式。

而是查看@Transactional。建议阅读 - &gt; thisthis&amp; this