仿QQ異地登錄強制下線功能的實現

一,仿QQ異地登錄強制下線功能

效果:同一個賬號,最後一個登錄的用戶會把前一個登錄後的用戶頂掉,被迫下線!

1,剖析登錄原理

登錄的後臺邏輯

  1. 準備一張賬戶信息表(賬號,密碼,是否禁用等字段)
  2. 查詢賬號密碼,如果正確就記錄session,並重定向到首頁。

而實現上述效果只需要稍加修改即可。

  1. 第一處修改,在賬戶信息表後新增一個字段,存儲登錄用戶的sessionId的值。
  2. 第二處修改,在登錄時,查詢賬號密碼正確並重定向到首頁之前添加一個步驟,就是更新當前賬號對應的sessionId字段。(不同瀏覽器的sessionId都是唯一的)
  3. 退出時,在清除session之前,把當前賬號對應的sessionId字段值置Null
  4. 寫一個輪詢方法,根據當前瀏覽器的sessionId到賬戶信息表查詢是否可以查到,如果查得到,說明賬號狀態正常,如果沒有查到,只能是該賬號被另一個瀏覽器進行訪問登錄了(會覆蓋掉原來的sessionId,改爲登錄人本機瀏覽器的sessionId

2,數據庫表設計

在這裏插入圖片描述

3,代碼實現

登錄請求方法

	 /**
     * todo 登錄請求
     */
    @PostMapping("/loginSubmit")
    public String loginSubmit(String username, String password, HttpSession session, Model model){
        List<Map> accountByPassword = busineService.getAccountByPassword(username, password);
        if(accountByPassword.size()>0){
            //用戶存在
            session.setAttribute("account",username);
            model.addAttribute("account",username);
			//##############   重點  #########################
            String sessionid = session.getId();
            int i = busineMapper.updateSessionIdByUsername(sessionid, username);
			//##############   重點  #########################
            return "redirect:/business/index";
        }else{
            //用戶不存在
            model.addAttribute("msg","用戶名或密碼錯誤");
            return "login";
        }
    }

退出登錄方法

 	/**
     * todo 退出系統
     */
    @RequestMapping("/logout")
    public String logout(HttpSession session){
        String username=(String) session.getAttribute("account");
        	//##############   重點  #########################
        int i = busineMapper.updateSessionIdByUsername(null, username);
			//##############   重點  #########################
        session.removeAttribute("account");
        return "forward:/business/login";
    }
    /**
     * todo 退出系統[通知下線時點擊確定跳轉此方法,不可以清空sessionId的值,因爲後來登錄的人要正常使用系統]
     */
    @RequestMapping("/logout1")
    public String logout1(HttpSession session){
        session.removeAttribute("account");
        return "forward:/business/login";
    }

登錄sql實現

	 // todo 登錄
    @Select(value = "select * from activiti_account where username=#{username} and password=#{password} and yxbz=1")
    List<Map> getAccountByPassword(@Param("username") String username, @Param("password") String password);

    //登錄時更新賬號表的sessionid字段
    @Update(value = "update activiti_account set sessionid=#{sessionid} where username=#{username}")
    int updateSessionIdByUsername(@Param("sessionid") String sessionid,@Param("username") String username);

    //輪詢檢查sessionid是否存在或是否被替換
    @Select(value = "select * from activiti_account where sessionid=#{sessionid}")
    Map checkSessionId(String sessionid);

js寫一個定時器,定時刷新賬號登錄狀態

$(function () {
			var is=true;
			setInterval(function () {
				if(is){
                    $.ajax({
                        url:"/business/checkSessionId",
                        type:"post",
                        dataType:"json",
                        success:function (data) {
                            if(data==0){
                                is=false;
                                layer.confirm('您的賬號已在異地登錄,請重新登錄', {
                                    btn: ['確定'] //按鈕
                                }, function(){
                                    //退出並跳轉登錄頁面
                                    window.location.href = "/business/logout1";
                                }, function(){
                                    //退出並跳轉登錄頁面
                                    window.location.href = "/business/logout1";
                                });
                            }
                        }
                    });
				}
            },5000);

輪詢方法

 	//輪詢檢查sesiosnid是否被替換,如果被替換,說明該賬號已在異地登錄
    @RequestMapping("/checkSessionId")
    @ResponseBody
    public int checkSessionId(HttpSession session){
        Map map = busineMapper.checkSessionId(session.getId());
        if(map!=null){
            //沒有被替換,賬號狀態正常
            return 1;
        }else{
            //賬號已在異地登錄,掉線通知
            return 0;
        }
    }

效果截圖
在這裏插入圖片描述

二,仿淘寶吱口令的功能實現

效果:在A平臺上覆制一段某商品分享的吱口令,然後打開B平臺,然後B平臺會自動識別用戶複製的吱口令,並打開該口令對應商品的詳情頁。

步驟分析:

  1. 在A平臺封裝某商品的詳情信息包括頁面鏈接,然後加密處理,生成一段字符串,供用戶複製。
  2. 打開B平臺,B平臺監聽剪切板中的吱口令信息,【監聽方式使用JS定時器請求後臺方法,該方法到剪切板中查看吱口令內容】,如果有吱口令信息,則解密吱口令並打開該口令對應商品的詳情頁。

這裏沒有具體實現,只給出實現思路,不過實現起來挺簡單的!
剪切板如何操作?

Java 操作剪貼板的類在 java.awt.* 包(及其子包)下,獲取系統剪貼板代碼

下面代碼實現用 Java 代碼獲取系統剪貼板對象,實現 複製粘貼 文本的例子。

package com.xiets.clipboard;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
public class Main {
    public static void main(String[] args) throws InterruptedException {
        // 把文本設置到剪貼板(複製)
        setClipboardString("Hello System Clipboard!");
        // 從剪貼板中獲取文本(粘貼)
        String text = getClipboardString();
        System.out.println("text: " + text);
    }
    /**
     * 把文本設置到剪貼板(複製)
     */
    public static void setClipboardString(String text) {
        // 獲取系統剪貼板
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        // 封裝文本內容
        Transferable trans = new StringSelection(text);
        // 把文本內容設置到系統剪貼板
        clipboard.setContents(trans, null);
    }
    /**
     * 從剪貼板中獲取文本(粘貼)
     */
    public static String getClipboardString() {
        // 獲取系統剪貼板
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        // 獲取剪貼板中的內容
        Transferable trans = clipboard.getContents(null);
        if (trans != null) {
            // 判斷剪貼板中的內容是否支持文本
            if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                try {
                    // 獲取剪貼板中的文本內容
                    String text = (String) trans.getTransferData(DataFlavor.stringFlavor);
                    return text;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

控制檯輸出
在這裏插入圖片描述
參考文章:https://blog.csdn.net/xietansheng/article/details/70478266

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