天天看點

利用HttpSessionListener監聽器實作使用者資料存儲

需求: web項目中,需要擷取通路該網站使用者的地區位置資料。 是以考慮直接用監聽器的方式來實作,即使用者第一次通路時,此時伺服器會建立session,取得request中的ip資訊,去調用封裝到service中擷取百度定位資訊的業務方法,最後将取得的定位資訊放置到session中,供session全局使用。

實作:

1、實作接口HttpSessionListener

@WebListener
public class WebHttpSessionListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent se) {
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
}
}
           

當浏覽器第一次通路應用時,會自動調用sessionCreated方法。我們可以在該方法中完成我們的主要邏輯。當session銷毀時,會調sessionDestroyed方法。(由于我使用的是springboot,是以我這裡使用注解方式注冊監聽器,添加@WebListener。)

2、根據需求,要擷取定位資訊必須要取到使用者的ip資訊,是以我們必須要取到request,我們知道,從session中我們是取不到request的,這裡我們會實作另一個監聽器:ServletRequestListener。用它,我們可以跟蹤到request的生命周期。

@WebListener
public class WebHttpSessionListener implements HttpSessionListener,ServletRequestListener{
private HttpServletRequest request;
@Override
public void sessionCreated(HttpSessionEvent se) {
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
      request = (HttpServletRequest) sre.getServletRequest();
}
}
           

這裡我們實作了HttpSessionListener,同時定義了一個HttpServletRequest 成員變量,它會在request初始化方法(requestInitialized)時進行指派,以供我們使用。

3、去調用封裝到service中擷取百度定位資訊的業務方法

擷取百度定位資訊的業務方法所在的業務類以被我們注冊成spring管理的bean,是以我們想在監聽器中調用需要首先獲得spring的上下文WebApplicationContext。 如何取到它呢? web容器初始化的時候會提供一個上下文,就是我們常見的ServletContext,同時還會定義一個ContextLoaderListener監聽器來監聽它的建立、銷毀等,WebApplicationContext就是在這個監聽器中被建立的,可以看下它監聽ServletContext建立時的方法。

@Override
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}
           

有興趣的可以繼續跟蹤下,WebApplicationContext最終被放在了ServletContext中,也就是說我們可以從ServletContext中取到我們所需要的WebApplicationContext。

@WebListener
public class WebHttpSessionListener implements ServletRequestListener,HttpSessionListener{
	private HttpServletRequest request;
	private MemberService memberService;
	@Override
	public void sessionCreated(HttpSessionEvent se) {
		WebApplicationContext application = (WebApplicationContext) se.getSession().getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
		memberService = (MemberService) application.getBean("memberService");
		se.getSession().setAttribute("memberAddress", memberService.getMemberAddress(request.getRemoteAddr()));
		System.out.println("一個session執行個體得到建立,并放入定位位址值");
	}
	@Override
	public void sessionDestroyed(HttpSessionEvent se) {
		System.out.println("一個session執行個體正在銷毀");
	}
	@Override
	public void requestDestroyed(ServletRequestEvent sre) {
	}
	@Override
	public void requestInitialized(ServletRequestEvent sre) {
		request = (HttpServletRequest) sre.getServletRequest();
	}
}
           

可以看到,我們成功取到想用的bean,并從其中取出我們所需要的定位資料放入到session屬性中,供我們使用。