国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java 多用戶登錄限制的實現方法

2019-11-26 13:35:46
字體:
來源:轉載
供稿:網友

最近比較空閑沒有項目做,于是乎捋了捋平時工作會遇到的一些常見問題,首先想到了多用戶登錄限制問題,下面就對此問題做一點思考講解。

相關閱讀:

Java Web開發防止多用戶重復登錄的完美解決方案

1、設計場景

  1)同一時刻不允許某個用戶多地登錄

  2)用戶已在A處登錄,現在從B處登錄是允許的,但會把A處擠掉(考慮到用戶在A處登錄后因某些情況跑到了B處,但還想繼續之前的工作,所以需要登錄系統)

  3)B處擠掉A后,A再做其它操作的時候系統會給出提示,該用戶在別處登錄,如不是本人操作可能密碼泄漏,請修改密碼。

2、思路導圖

  每個用戶登錄的時候,通常我們會將用戶信息存入session,以便用戶進行操作的時候系統方便得到用戶的基本信息。但這個session具有私有性,只對當前用戶可見(如果同意用戶在不同瀏覽器登錄會得到不同的session,這也是為什么可以多用戶登錄的根源所在)。那么接著問題就來了,某個用戶登錄的時候如何能知道自己是否在線,相信聰明的你已經想到,這還不好半,把在線的用戶信息存儲在一個公共的地方問題不就迎刃而解了么,網上一查,解決方案無出其右,大致為以下兩種

  1)數據庫中標識在線用戶

  2)存儲到application中

  經過重重考慮,我們會發現方案一需要解決許多棘手的問題(用戶異常退出未來得及修改狀態,頻繁訪問數據庫影響性能等),這對于一個要求完美的你來說顯然是不合時宜的,于是我們采用了方案二,將在線用戶信息保存到application中,具體設計如下。

  1)登錄流程圖

  2)被擠掉后操作流程圖

3、代碼

  1)登錄方法

@RequestMapping(value = "/login", method = RequestMethod.POST)public String login(String userName, String password, RedirectAttributes redirectAttributes, HttpServletRequest request) {//判斷用戶是否已經在線及處理(已在線則剔除)String loginLimite = limiteLogin.loginLimite(request, userName);//判斷用戶名、密碼是否正確String result = userService.login(userName, password);if (result.equals("success")) {request.getSession().setAttribute("now_user", userService.findByUserName(userName));//創建token及驗證String jwtToken = tokenService.createUserAuthToken(userService.findByUserName(userName));//生成tokenSystem.out.println(jwtToken);UserAuthenticationToken authToken = tokenService.retrieveUserAuthToken(jwtToken);//token解析System.out.println(authToken.isAuthenticated());System.out.println("id = " + UserAuthenticationToken.getCurrentToken().getUserUuid());//用戶掉線,登錄后重定向到保存的鏈接Object url = request.getSession().getAttribute("redirect_link");if (url != null) {request.getSession().removeAttribute("redirect_link");return "redirect:" + url.toString();}return "index";}redirectAttributes.addFlashAttribute("message", result);return "redirect:/other/toLogin";}

  2)登錄判斷是否已經在線

@Service@Transactionalpublic class LimiteLogin {private static Logger log = Logger.getLogger(SessionListener.class);private static Map<String, String> loginUserMap = new HashMap<>();//存儲在線用戶private static Map<String, String> loginOutTime = new HashMap<>();//存儲剔除用戶時間@Autowiredprivate UserService userService;public String loginLimite(HttpServletRequest request, String userName) {User user = userService.findByUserName(userName);String sessionId = request.getSession().getId();for (String key : loginUserMap.keySet()) {//用戶已在另一處登錄if (key.equals(user.getUserName()) && !loginUserMap.containsValue(sessionId)) {log.info("用戶:" + user.getUserName() + ",于" + DateUtil.dateFormat(new Date(), "yyyy-MM-dd HH:mm:ss") + "被剔除!");loginOutTime.put(user.getUserName(), DateUtil.dateFormat(new Date(), "yyyy-MM-dd HH:mm:ss"));loginUserMap.remove(user.getUserName());break;}}loginUserMap.put(user.getUserName(), sessionId);request.getSession().getServletContext().setAttribute("loginUserMap", loginUserMap);request.getSession().getServletContext().setAttribute("loginOutTime", loginOutTime);return "success";}}

  3)登錄攔截器(未登錄跳轉登錄頁)

public class LoginInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();User user = (User) session.getAttribute("now_user");if (session.getAttribute("now_user") == null) {response.sendRedirect(request.getContextPath() + "/other/toLogin");return false;}//多用戶登錄限制判斷,并給出提示信息boolean isLogin = false;if (user != null) {Map<String, String> loginUserMap = (Map<String, String>) session.getServletContext().getAttribute("loginUserMap");String sessionId = session.getId();for (String key : loginUserMap.keySet()) {//用戶已在另一處登錄if (key.equals(user.getUserName()) && !loginUserMap.containsValue(sessionId)) {isLogin = true;break;}}}if (isLogin) {Map<String, String> loginOutTime = (Map<String, String>) session.getServletContext().getAttribute("loginOutTime");session.setAttribute("mess", "用戶:" + user.getUserName() + ",于 " + loginOutTime.get(user.getUserName()) + " 已在別處登錄!");loginOutTime.remove(user.getUserName());session.getServletContext().setAttribute("loginUserMap", loginOutTime);response.sendRedirect(request.getContextPath() + "/other/toLogin");return false;}return super.preHandle(request, response, handler);}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {super.afterCompletion(request, response, handler, ex);}}

  4)在session銷毀的時候,把loginUserMap中保存的鍵值對清除

public classSessionListener implements HttpSessionListener {private static Logger log = Logger.getLogger(SessionListener.class);@Overridepublic void sessionCreated(HttpSessionEvent event) {}@Overridepublic void sessionDestroyed(HttpSessionEvent event) {HttpSession session = event.getSession();String sessionId = session.getId();//在session銷毀的時候,把loginUserMap中保存的鍵值對清除User user = (User) session.getAttribute("now_user");if (user != null) {Map<String, String> loginUserMap = (Map<String, String>) event.getSession().getServletContext().getAttribute("loginUserMap");if(loginUserMap.get(user.getUserName()).equals(sessionId)){log.info("clean user from application : " + user.getUserName());loginUserMap.remove(user.getUserName());event.getSession().getServletContext().setAttribute("loginUserMap", loginUserMap);}}}}

  5)web.xml

<!-- session listener 多用戶登錄限制,退出清除session信息的同時清除application中存放用戶登錄信息--><listener><listener-class>com.service.limitelogin.SessionListener</listener-class></listener>

  6)頁面代碼(用于給出提示的同時,清除被擠掉用戶的session信息,否則提示信息會一直顯示) 

<script type="text/javascript">$(document).ready(function () {var message='${mess}';if (message != "") {$.ajax({type: 'GET',async: false,cache: false,url: '/other/clearUserSession',dataType: '',data: {},success: function (data) {}});$('#mess').html(message);}});</script>

  7)清除擠掉用戶session代碼

/*** 多用戶登錄限制,清除session信息(登錄信息、提示信息)** @param request* @return*/@ResponseBody@RequestMapping(value = "/clearUserSession")public String clearUserSession(HttpServletRequest request) {HttpSession httpSession = request.getSession();//httpSession.invalidate();httpSession.removeAttribute("now_user");httpSession.removeAttribute("mess");return "success";}

到此開發工作完成

4、運行結果

以上所述是小編給大家介紹的Java 多用戶登錄限制的實現方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 逊克县| 集安市| 永善县| 吐鲁番市| 洱源县| 新昌县| 绩溪县| 云浮市| 西城区| 阜阳市| 安丘市| 冕宁县| 峨眉山市| 汉沽区| 云南省| 策勒县| 华阴市| 临沧市| 缙云县| 延庆县| 宜春市| 皋兰县| 黄石市| 西和县| 惠安县| 尼玛县| 山阴县| 蓬莱市| 高淳县| 蓬莱市| 长沙县| 祁阳县| 汝南县| 高阳县| 唐海县| 禹州市| 大宁县| 盘山县| 罗田县| 仙桃市| 上蔡县|