java-同一用戶頂替操做(session過時或無效)

同一帳號後者登陸前者被強制退出:(能夠經過監聽器或過濾器進行監測session是否無效)javascript

首先根據輸入的用戶名和密碼作驗證,經過驗證查詢用戶信息。在用戶信息不爲空的前提下,比較靜態變量中的sessionid和瀏覽器session獲取的getId(),判斷兩個值是否一致,若一致,則經過 正常走流程,若不一致,則返回登陸頁面,session設置msg,提示「帳戶失效或異地登陸」;

html

web.xml:java

<session-config>
        <session-timeout>180</session-timeout><!--session過時時間設置-->
</session-config>

controller:web

public static Map<HttpSession, String> loginSessionList = new HashMap<>();//保存當前登陸的全部用戶 //登陸方法
 @ResponseBody @RequestMapping(value = "/login", method = RequestMethod.POST) public ResponseResult login(User user, HttpServletRequest request,HttpSession session) { //.............................
            session.setAttribute("username", user.getLoginName()); session.setAttribute("logoutType", "0"); checkLoginSession(session,user.getLoginName()); loginSessionList.put(session, user.getLoginName()); //............................. 
 } /** * 檢查用戶是否已經登陸 * @param session * @param loginName * @return
     */
    private String checkLoginSession(HttpSession session,String loginName) { String checkValue = "0"; HttpSession reSession = null; try { Set<HttpSession> keys = loginSessionList.keySet(); for (HttpSession key : keys) { if (loginSessionList.get(key).equals(loginName) && !session.equals(key)) { //key.invalidate();//若是該用戶名有登陸,則使前者失效(適用於方法一)
                    key.setAttribute("logoutType", "1"); checkValue = "1"; reSession = key; break; } } if (checkValue.equals("1") && reSession != null) { //防止用戶直接關閉瀏覽器
 loginSessionList.remove(reSession); } } catch (Exception e) { // TODO 自動生成的 catch 塊
 e.printStackTrace(); } return null; }

參考連接:servlet/filter/listener/interceptor區別與聯繫ajax

方法一:(使用 HttpSessionListener進行監聽)瀏覽器

使用監聽器監聽對頁面跳轉很差進行控制session

web.xml:app

<!-- session監聽 -->
    <listener>
          <listener-class>net.nblh.system.shiro.OnlineUserListener</listener-class><!--監聽器類的路徑-->
    </listener>

 OnlineUserListener:異步

package net.nblh.system.shiro; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import net.nblh.system.controller.SystemController; public class OnlineUserListener implements HttpSessionListener{ /** * 監聽session建立 */ @Override public void sessionCreated(HttpSessionEvent arg0) { // TODO 自動生成的方法存根
 } /** * 監聽session銷燬 */ @Override public void sessionDestroyed(HttpSessionEvent event){ try { // TODO 自動生成的方法存根
            HttpSession session = event.getSession(); // 取得登陸的用戶名
            String username = (String) session.getAttribute("username"); SystemController.loginSessionList.remove(session); System.out.println(username + "退出。"); } catch (Exception e) { // TODO 自動生成的 catch 塊
 e.printStackTrace(); } } }

方法二:(使用Filter進行過濾)ide

web.xml:

<!-- session過濾器 -->
    <filter>
        <filter-name>sessionFilter</filter-name>
        <filter-class>net.nblh.system.shiro.SessionFilter</filter-class><!--過濾器類的路徑-->
    </filter>
    <filter-mapping>
            <filter-name>sessionFilter</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>

SessionFilter:

package net.nblh.system.shiro; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.nblh.system.controller.SystemController; import net.nblh.system.entity.SysConfigItemValue; import net.nblh.utils.StringUtils; /** * Session攔截器 * @author lijd * */
public class SessionFilter implements Filter { @Override public void destroy() { // TODO 自動生成的方法存根
 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { // TODO 自動生成的方法存根
            HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; HttpSession session = httpRequest.getSession(); //異地頂替帳號登陸url
            String toLoginUrl = session.getServletContext().getContextPath()+"/system/tologin2";//列席人登陸頁面 //session過時登陸url
            String sessionLoginUrl = StringUtils.isNotEmpty(SysConfigItemValue.getValue("sessionOutTimeToURL"))?SysConfigItemValue.getValue("sessionOutTimeToURL"):toLoginUrl; String url = httpRequest.getRequestURI(); String path = url.substring(url.lastIndexOf("/")); /*// 判斷是否爲ajax請求 if (httpRequest.getHeader("x-requested-with") != null && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) { //該請求是 AJAX 異步HTTP請求 if (session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) { SystemController.loginSessionList.remove(session); session.invalidate(); httpResponse.addHeader("sessionstatus", "timeOut");//Session已過時 httpResponse.addHeader("loginPath", sessionLoginUrl); chain.doFilter(request, response); }else { chain.doFilter(request, response);// 不可少,不然請求會出錯 } }*/
            if (path.indexOf("sessionTimeOut") != -1 && session.getAttribute("shiroSavedRequest") != null && session.getAttribute("currentUser") == null) { SystemController.loginSessionList.remove(session); session.invalidate(); //session過時
                toLoginUrl(response,"會話已過時",sessionLoginUrl); } else if(session.getAttribute("logoutType") != null && session.getAttribute("logoutType").equals("1")){ SystemController.loginSessionList.remove(session); session.invalidate(); // logoutType=0:正常,logoutType=1:異地登陸 
                toLoginUrl(response,"用戶已在別處登陸",toLoginUrl); } else { try { chain.doFilter(request, response); } catch (Exception e) { SystemController.loginSessionList.remove(session); session.invalidate(); toLoginUrl(response,"會話已過時!",sessionLoginUrl); } } } catch (Exception e) { // TODO 自動生成的 catch 塊
 e.printStackTrace(); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO 自動生成的方法存根
 } /** * session無效後跳轉指定路徑 * @param response * @param message * @param loginUrl */
    private void toLoginUrl (ServletResponse response,String message,String loginUrl) { String str = "<script language='javascript'>alert('"+ message +"');" + "top.location.href='" + loginUrl + "';</script>"; response.setContentType("text/html;charset=UTF-8");// 解決中文亂碼
        try { PrintWriter writer = response.getWriter(); writer.write(str); writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); } } }

使用響應頭進行JS控制:

httpResponse.addHeader("sessionstatus", "timeOut");//Session已過時
httpResponse.addHeader("loginPath", sessionLoginUrl); chain.doFilter(request, response);

js:

<script type="text/javascript"> $(document).ajaxComplete(function(event, xhr, settings) { if(xhr.getResponseHeader("sessionstatus")=="timeOut"){ if(xhr.getResponseHeader("loginPath")){ alert("會話過時,請從新登錄!"); window.location.replace(xhr.getResponseHeader("loginPath")); }else{ alert("請求超時請從新登錄 !"); } } }); </script>
相關文章
相關標籤/搜索