標籤:zed login == com 訪問 同步 標記 sse 會話
實現方法:攔截器+session儲存
攔截器初始化時,即在@PostConstruct註解的initMethod方法中讀取資料庫的isystem對象,該對象記錄了網站訪問量的資訊。
攔截器銷毀時,即在@PreDestroy註解的destroyMethod方法中向資料庫更新isystem對象。
攔截器的初始化和銷毀都只有在應用啟動和關閉的時候才被調用,因此減少了對資料庫的訪問。
SpringMVC中,每一次請求控制器,都會先執行攔截器的preHandle方法,在該方法內先查看session中的一個標誌accessedFlag,如果該標誌不存在,說明此次會話沒有被統計,因此在isystem對象中增加一次訪問量,並向session添加標誌accessedFlag,下一次訪問時,該session不再添加訪問量,即一個session算訪問一次。並且在session中儲存isystem對象,並於網頁顯示資料的調用。
為了保證並發的正確性,局部代碼塊使用同步鎖,見下面紅色部分。
總結:攔截器有一個靜態屬性isystem,使用者第一次請求時,都會更新這個屬性的值。使用者的每一次請求都會把該屬性放入到使用者的session中去。因此,B使用者第一次訪問後,A使用者第二次訪問時(和第一次訪問共用一個session),A使用者的session中的isystem也會被更新。
攔截器類如下:
package com.wuchao.utils.interceptor;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.wuchao.blog.system.bo.intf.IsystemBo;import com.wuchao.blog.system.po.Isystem;import com.wuchao.blog.user.controller.LoginController;import com.wuchao.utils.config.SpringContextHolder;public class RequestInterceptor extends HandlerInterceptorAdapter {private static Logger log = Logger.getLogger(LoginController.class); @Resource(name="isystemBo")public IsystemBo isystemBo;@Resource(name="springContextHolder")SpringContextHolder springContextHolder;public static Isystem isystem;//請求控制器前,處理請求@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {try {log.info("RequestInterceptor");//網站訪問量+1if(isystem==null) {log.info("isystem==null");isystem = isystemBo.getIsystemByDefault();}if(isystem!=null) {//每一個session理論上只能記一次訪問,因此在session裡面存一個訪問標記,如果存在標記,則不再計算此次訪問String accessedFlag = "accessedFlag";if(request.getSession().getAttribute("accessedFlag")==null) {//同步鎖synchronized(this) {log.info("網站訪問量+1,存入session");isystem.setAmountOfAccess(isystem.getAmountOfAccess()+1);request.getSession().setAttribute("Isystem", isystem);request.getSession().setAttribute("accessedFlag", accessedFlag);}}}}catch(Exception e) {e.printStackTrace();throw e;} return true; }@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {}/* * 執行個體化時執行的操作 */@PostConstruct public void initMethod() throws Exception { log.info("initMethod 被執行"); //載入isystem對象if(isystem==null) {log.info("載入isystem");isystem = isystemBo.getIsystemByDefault();} } /* * 銷毀前執行的操作 */ @PreDestroy public void destroyMethod() throws Exception { log.info("destroyMethod 被執行"); //儲存isystem if(isystem!=null) { isystemBo.saveIsystem(isystem); } } }
網站訪問量統計功能的實現