Spring——Web作用域:RequestContextListener

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章