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中的數據進行交互!