Spring——RequestContextListener作用
在Spring API中提供了一个非常便捷的工具类RequestContextHolder,能够在Controller中获取request对象和response对象,使用方法如下
// 获取request: HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); // 获取session: HttpSession session = request.getSession(); // 获取servletContext ServletContext application = session.getServletContext(); // 获取response: HttpServletResponse resp = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();
注意:是如果直接使用这个工具类,则会抛出一个空指针异常。
原因:需要先在web.xml配置 RequestContextListener 监听器:
<!-- 用于管理请求相关内容的监听器,只有配置了这个监听器才能使用RequestContextHolder --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
RequestContextListener
原理:RequestContextListener实现了ServletRequestListener ,在其覆盖的requestInitialized(ServletRequestEvent requestEvent)方法中,将request最终设置到了RequestContextHolder中.
public class RequestContextListener implements ServletRequestListener { private static final String REQUEST_ATTRIBUTES_ATTRIBUTE = RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES"; @Override public void requestInitialized(ServletRequestEvent requestEvent) { //判断是否是 HttpServletRequest if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) { throw new IllegalArgumentException( "Request is not an HttpServletRequest: " + requestEvent.getServletRequest()); } //针对 HttpServletRequest 进行操作 //1.从事件对象中获取 request 对象 HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest(); //2.将 request 设置到 servletRequestAttributes 中 ServletRequestAttributes attributes = new ServletRequestAttributes(request); //3.反过来将 servletRequestAttributes 设置到 request 中 request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes); LocaleContextHolder.setLocale(request.getLocale()); //4.再将 request 包装的 servletRequestAttributes 放入 RequestContextHolder RequestContextHolder.setRequestAttributes(attributes); } }
ContextLoaderListener 和 RequestContextListener 区别
ContextLoaderListener:只负责监听web容器的启动和关闭,而web服务器收到的每次请求都会通知RequestContextListener这个监听器。在整合spring容器时使用ContextLoaderListener,它实现了ServletContextListener监听器接口,ServletContextListener只负责监听web容器启动和关闭的事件。
RequestContextListener:实现ServletRequestListener监听器接口,该监听器监听HTTP请求事件,web服务器接收的每一次请求都会通知该监听器。spring容器启动和关闭操作由web容器的启动和关闭事件触发,但如果spring容器中的Bean需要request,session,globalsession作用域的支持,spring容器本身就必须获得web容器的HTTP请求事件,以HTTP请求的事件”驱动”Bean作用域的控制逻辑。也就是说只有配置了RequestContextListener,spring容器中的bean才能与到request、session、globalSession中的数据进行交互!