//登录页面 login.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="./js/vue.js"></script>
<title>登录</title>
<%
String msg = (String)(request.getAttribute("msg")==null?"":request.getAttribute("msg"));
%>
<script type="text/javascript">
function show(){
if('<%=msg%>'!=''){
alert('<%=msg%>');
}
}
</script>
</head>
<body style="text-align: center" οnlοad="show();">
<form action="${pageContext.request.contextPath}/login.do" method="post">
<table border="1">
<tr>
<td align="center" colspan="2">
<h3>用户登录</h3>
</td>
</tr>
<tr>
<td align="right">
用户名
</td>
<td align="left">
<input type="text" id="userName" name="userName">
</td>
</tr>
<tr>
<td align="right">
密 码
</td>
<td align="left">
<input type="password" id="password" name="password">
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" value="登录"> <input type="reset" value="重置">
</td>
</tr>
</table>
</form>
</body>
</html>

  //主页面 main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录成功</title>
<script type="text/javascript" src="./js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="./js/vue.js"></script>
</head>
<%
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","No-cache");
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "No-store");
String userName = "";
userName = (String)(session.getAttribute("userName")==null?"":session.getAttribute("userName"));
%>
<script type="text/javascript">
var count;
var userMsg = '';
var i =0;
function checkUserOnline(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/checkUserOnline.do",
dataType : "text",
success:function(data){
userMsg = data;
//alert(JSON.stringify(userMsg))
},
error:function(){
alert("获取用户信息失败!");
clearInterval(count);
reLogin();
}
});
if(userMsg=='null'||userMsg==''|| userMsg == 'undefined'){
return;
}else{
//alert(JSON.stringify(userMsg));
clearInterval(count);
reLogin();
}
}
function reLogin(){
window.location = "login.jsp";
} function checkLogin(){
alert("检查");
count = setInterval("checkUserOnline()",5000);
}
</script>
<body onclick="checkLogin()">
<%
if(!"".equals(userName)){
out.print("登陆成功!<br/>用户名:<span id='userName'>"+userName+"</span><br/><input type='button' value='重新登陆' οnclick='reLogin();'/>");
}
%>
</body>
</html>

  //控制类 LoginController

package com.zjn.oneLogin.dengLu;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
public class LoginController{
/**
* 用户和Session绑定关系
*/
public static final Map<String, HttpSession> USER_SESSION = new HashMap<String, HttpSession>();
/**
* seeionId和用户的绑定关系
*/
public static final Map<String, String> SESSIONID_USER = new HashMap<String, String>();
@RequestMapping("/login")
@ResponseBody
public Map<String,Object>toLogin(HttpServletRequest request, HttpServletResponse response) throws Exception{
//获取请求命令
request.setCharacterEncoding("utf-8");
String servletPath = request.getServletPath();//获取请求路径
String uri = servletPath.substring(1, servletPath.lastIndexOf(".do")); try{
//登录
if ("login".equals(uri)){
HttpSession session = request.getSession();
String userName = request.getParameter("userName");
String password = request.getParameter("password"); if (userName != null && !"".equals(userName.trim())){
//登录成功
if (login(userName, password)){
//处理用户登录(保持同一时间同一账号只能在一处登录)
userLoginHandle(request); //添加用户与HttpSession的绑定
USER_SESSION.put(userName.trim(), session);
//添加sessionId和用户的绑定
SESSIONID_USER.put(session.getId(), userName);
System.out.println("添加sessionId和用户的绑定 ==="+session.getId());
System.out.println("用户[" + userName + "] 已上线...");
session.setAttribute("userName", userName);
session.removeAttribute("userMsg");//从session中移除用户信息
//重定向到首页
response.sendRedirect("main.jsp"); }
//登录失败
else{
System.out.println("用户[" + userName + "] 登录失败...");
request.setAttribute("msg", "登录失败,请重新登录!");
//response.sendRedirect("login.jsp");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
else{
System.out.println("用户[" + userName + "] 登录失败..."); request.setAttribute("msg", "登录失败,请重新登录!"); //response.sendRedirect("login.jsp");
request.getRequestDispatcher("login.jsp").forward(request, response);//跳转到用户页面,返回请求响应对象
}
}else if ("reLogin".equals(uri)){
//重新登陆
HttpSession session = request.getSession();
String userName = (String)session.getAttribute("userName");
if (session != null){
//销毁相关session
//USER_SESSION.remove(SESSIONID_USER.remove(session.getId()));
session.invalidate();
}
if (userName != null && !"".equals(userName)){
System.out.println("用户[" + userName + "] 已下线...");
}
//重定向到登录页面
response.sendRedirect("login.jsp");
} }
catch (Exception e){
System.out.println(e.getClass() + e.getMessage());
PrintWriter out = response.getWriter();
out.print("服务器内部错误!");
}
return null; } /**
*
* Description:用户登录时的处理 <br>
* @param request
* @see
*/
private void userLoginHandle(HttpServletRequest request){
//当前登录的用户
String userName = request.getParameter("userName");
System.out.println("userName=="+userName);
//当前sessionId
//String sessionId = request.getSession().getId(); //删除当前sessionId绑定的用户,用户--HttpSession
//USER_SESSION.remove(SESSIONID_USER.remove(sessionId));
//删除当前登录用户已绑定的HttpSession
HttpSession session = USER_SESSION.remove(userName);//map中的remove方法返回删除value值 if (session != null){
//删除已登录的sessionId绑定的用户
SESSIONID_USER.remove(session.getId());
session.removeAttribute("userName");
session.setAttribute("userMsg", "您的账号已经在另一处登录,您被迫下线!");
}
} /**
*
* Description: 模拟DB登录判断<br>
* @param userName 用户
* @param password 密码
* @return
* @see
*/
private boolean login(String userName, String password){
return ("peizhongxian".equals(userName) && "123456".equals(password));
} /**
* 判断用户是否同时登陆同一个用户
*
* */
@RequestMapping(value="/checkUserOnline")
@ResponseBody
public void checkUserOnline(HttpServletRequest request,HttpServletResponse response) throws IOException{
HttpSession session=request.getSession();
PrintWriter out = response.getWriter();
out.print(session.getAttribute("userMsg"));
} }

  //监听器 MyListener

package com.zjn.oneLogin.dengLu;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; public class MyListener implements HttpSessionListener { /**
* 实现HttpSessionListener接口监听 监听session的创建事件
*/
public void sessionCreated(HttpSessionEvent se){
String sessionId = se.getSession().getId();
System.out.println("创建session sessionId= " + sessionId);
} /**
* 实现HttpSessionListener接口监听 监听session的销毁事件
*/
public void sessionDestroyed(HttpSessionEvent se){
String sessionId = se.getSession().getId();
System.out.println("sessionId========="+sessionId);
//当前session销毁时删除当前session绑定的用户信息
//同时删除当前session绑定用户的HttpSession
LoginController.USER_SESSION.remove(LoginController.SESSIONID_USER.remove(sessionId)); System.out.println("销毁session sessionId= " + sessionId);
} }

  //web.xml 文件

 <listener>
<listener-class>com.zjn.oneLogin.dengLu.MyListener</listener-class>
</listener>

  

java保持同一时间同一账号只能在一处登录的更多相关文章

  1. SpringMVC实现账号只能在一处登陆

    一.问题引导 在Web开发中,实现一个账号只能在一处登陆有两种形式:1.当某个账号在某处登陆后,如果再在其他处登陆,将前一个账号挤掉:2.当某个账号登陆后,此账号在其他设备登陆提示已经登陆,无法登陆. ...

  2. asp.net mvc 简单实现一个账号只能在一个地方登录

    原理:  假设用户在机器A登陆后,  这时用户再次在机器B登陆,会以当前会话的SessionID作为键,用户id作为值,插入dictionary集合中,集合再保存在application(保存在服务器 ...

  3. shiro实现账号同一时间只能在一处登录(非单点登录)

    <bean id="myRealm" class="com.sys.shiro.MyRealm" /> <bean id="sess ...

  4. [Java]Java日期及时间库插件 -- Joda Time.

    来到新公司工作也有一个多月了, 陆陆续续做了一些简单的项目. 今天做一个新东西的时候发现了 Joda Time的这个东西, 因为以前用的都是JDK原生的时间处理API, 大家都知道Java原生的时间处 ...

  5. Java中日期时间API小结

    Java中为处理日期和时间提供了大量的API,确实有把一件简单的事情搞复杂的嫌疑,各种类:Date Time Timestamp Calendar...,但是如果能够看到时间处理的本质就可以轻松hol ...

  6. php 实现同一个账号同时只能一个人登录

    php 实现同一个账号同时只能一个人登录 张映 发表于 2015-01-22 分类目录: php 标签:mysql, nginx, openfire, php, redis 以前考虑过这个问题,今天实 ...

  7. (Java)微信之个人公众账号开发(二)——接收并处理用户消息(下)

    接下来,我们再讲一下图文消息: 如图: 大家可以先从开发者文档中了解一下图文消息的一些参数: 如上图,用户回复4时,ipastor返回了几条图文消息,上图中属于多图文消息,当然还有单图文消息,图文消息 ...

  8. Java 8 日期时间API

    Java 8一个新增的重要特性就是引入了新的时间和日期API,它们被包含在java.time包中.借助新的时间和日期API可以以更简洁的方法处理时间和日期; 在介绍本篇文章内容之前,我们先来讨论Jav ...

  9. java学习第13天( java获取当前时间,有关大数据的运算及精确数字运算,Date类)

    一 java获取当前时间 学习一个函数,得到当前时间的准确值 System.currectTimeMillis(). 可以得到以毫秒为单位的当前时间.它主要用于计算程序运行时间,long start= ...

随机推荐

  1. uwsgi+nginx的三种配置方式

    第一种 vi /etc/uwsgi.ini uwsgi --reload uwsgi.pid vi /etc/nginx/conf.d/iot.conf service nginx restart 第 ...

  2. Python正则表达式处理的组是什么?

    在学习正则表达式处理开始阶段,对于匹配对象的group数据没有理解,查了资料进行验证测试,终于理解了. 组其实与组匹配模式相关,就是在匹配的正则表达式中使用小括号"()"括起来的任 ...

  3. 第12.7节 Python标准库内置模块小结

    本章老猿走马观花般的介绍了一下前面没有介绍的内置模块,内容很多,介绍的很泛,介绍的目的只是让大家知道有哪些内置模块.大致的功能有哪些,以后要使用时大家可以再去详细研究.之所以采用这种方式,一是老猿时间 ...

  4. 乌云wooyun网站硬盘复活

    AWD比赛防止没有网络,在移动硬盘里面准备一个乌云漏洞库. 之前也想过弄一个乌云的镜像网站,无奈学生机性能太低下了,部署到公网上服务器存储空间都不够,只能部署在本地硬盘了. 乌云镜像的开源地址:htt ...

  5. PHP代码审计分段讲解(12)

    28题 <!DOCTYPE html> <html> <head> <title>Web 350</title> <style typ ...

  6. Codeforces Edu Round 49 A-E

    A. Palindromic Twist 由于必须改变.所以要使\(a[i] = a[n - i + 1]\). 要么同向走,但必须满足之前的\(a[i] = a[n - i + 1]\). 要么相遇 ...

  7. 题解-CF163E e-Government

    题面 CF163E e-Government 给 \(n\) 个字符串 \(s_i\) 和 \(q\) 个询问,刚开始字符串都服役.每次操作将集合中的一个字符串设为退役或服役,或查询与文本串 \(S_ ...

  8. 题解-[HNOI2016]序列

    题解-[HNOI2016]序列 [HNOI2016]序列 给定 \(n\) 和 \(m\) 以及序列 \(a\{n\}\).有 \(m\) 次询问,每次给定区间 \([l,r]\in[1,n]\),求 ...

  9. 操作系统精髓与设计原理(九)——I/O管理和磁盘调度

    文章目录 I/O设备 I/O功能组织 直接存储器访问 操作系统设计问题 设计目标 IO功能的逻辑结构 I/O缓冲 单缓冲 双缓冲 循环缓冲 缓冲的作用 磁盘调度 磁盘性能参数 磁盘调度策略 先进先出 ...

  10. Angular:惰性加载的模块

    ①通过ng new angular-module创建一个全新的angular应用,默认不选路由 ②通过一下命令分别创建2个模块和1个组件 ng g m hx1 ng g c hx1 ng g m hx ...