【一】单一登录/单点登录
单一登录:
单点登录:
【二】实现思路、实现代码
实现代码:
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import gentai.webapp.domain.User;
import gentai.webapp.service.UserService;
import gentai.webapp.util.MD5Util;
@WebServlet("/Loginservlet")
public class Loginservlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public static Map<String,HttpSession> USERID_SESSION = new ConcurrentHashMap<String,HttpSession>();//uid--session
public Loginservlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
MD5Util md=new MD5Util();
String uid = request.getParameter("username");//当前登录的用户(new_session)
String upassword = request.getParameter("password");
UserService userService = new UserService();
User user = userService.findUserByUId(uid);
HttpSession new_session = request.getSession();
//判断部分
try {
System.out.println(System.currentTimeMillis()+"现登录的"+new_session);
if(user!=null&&user.getUpasswd().equals(md.md5Encode(upassword))) {
// 1.实现单一登录 踢人效果
if(USERID_SESSION.get(user.getUid()) == null) {
//第一次登录
USERID_SESSION.put(user.getUid(), new_session);
new_session.setAttribute("otherLogin", false);
}else {
//第二次登录
HttpSession old_session=USERID_SESSION.get(user.getUid());
/*old_session.removeAttribute("user");*/
old_session.setAttribute("otherLogin", true);
USERID_SESSION.remove(uid);
new_session.setAttribute("otherLogin", false);
USERID_SESSION.put(user.getUid(), new_session);
}
String sign = user.getUsign();
new_session.setAttribute("usign", sign);
new_session.setAttribute("uid",uid);
response.sendRedirect(request.getContextPath()+"/authority.jsp");
}else {
//用户为空或者密码有问题
request.setAttribute("loginsign", "fail");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
校验:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
@WebServlet("/checkOtherLogin.do")
public class CheckOtherLogin extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
Map<String,Object> map = new HashMap<>();
if (!(boolean) req.getSession().getAttribute("otherLogin")) {
map.put("single", true);
}else {
map.put("single", false);
}
req.setAttribute("map", map);
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
out.write(new JSONObject(map).toString());
}
}
退出:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/ExitServlet")
public class ExitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ExitServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
// 把session内的所有属性都清除
session.invalidate();
// 跳转到登陆页面
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
前台登录界面省略:
登录成功后的界面(需添加的必要代码):
<%@page import="java.util.*" %>
<%
Map<String, Object> map = (Map<String, Object>) request.getSession().getAttribute("map");
%>
<script>
var getting = {
url:'${pageContext.request.contextPath }/checkOtherLogin.do',
dataType:'json',
success:function(data){
if(data.single == false) {
alert("您的帐号在异地登录!");
window.location = "${pageContext.request.contextPath }/login.jsp";
}
else {
$.ajax(getting);
}
}
}
$.ajax(getting);
window.onbeforeunload = function(){ //关闭浏览器的时候退出
$.post('${pageContext.request.contextPath }/ExitServlet.do')
}
</script>
【三】遗留问题、解决方法
遗留问题:
项目部署后,隔天打开,成功登录后停留在空白界面。控制台没有任何错误信息,以及network处没有加载一些东西。但已加载的loginservlet处于200状态。
有的时候过几个小时,会出现同一网址,不同用户登录,有的可以成功登录,有的不能登录成功。
解决方法:还没有找到问题出在哪里。。。
不知道出现上述问题,是逻辑的问题,还是session的问题,还是servlet的问题,还是checkotherlogin轮询的问题。