现在的位置: 首页 > 编程语言 > 正文

Javaweb实现账号单一登录,防止同一账号重复登录(踢人效果)

2020年02月13日 编程语言 ⁄ 共 9693字 ⁄ 字号 评论关闭

实现了Java web开发账号单一登录的功能,防止同一账号重复登录,后面登录的踢掉前面登录的,使用过滤器Filter实现的。可以先下载项目下来测试下效果。

有博客写的是没个一段时间(比如500ms)读取后台的session进行验证,这种方法除了会占用资源,还会出现访问session(请求1)的返回值和自己提交请求(请求2)的返回值发生冲突。比如请求1先提交,此时请求1的返回值还未返回到前端,请求2提交,实际上我们想要的是请求1的返回值先返回,然后再返回请求2的返回值,但是这不是肯定会发生的,ajax的机制所导致的,具体什么原因没查到。总之出现了请求2先返回了返回值,这时候请求1接收到了请求2的返回值,妥妥的前端出现错误,但是后台却是成功的。

下面进入主题

工程下载链接:链接: https://pan.baidu.com/s/1Rp09wv7hTJLqx9DiQ_KSeA 提取码: xyym

其中:jquery-1.11.3.js是网上的工具

建立两个简单的界面

登录界面:为了简单没有设置密码,直接输入账号点击登录就行

// index.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>" rel="external nofollow" rel="external nofollow" > <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css" rel="external nofollow" rel="external nofollow" > --> </head> <body> <input id="username" name="username" type="text"> <!-- <a href="singlecount.jsp" rel="external nofollow" target="_self"> --> <button id="btnlogin" name="btnlogin">登录</button><!-- </a> --> <!-- 引入jQuery --> <script type="text/javascript" src="js/jquery-1.11.3.js"></script> <script type="text/javascript" src="js/jsSubmit.js"></script> </body></html>

主页面:简单的一个提交按钮

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>" rel="external nofollow" rel="external nofollow" > <title>My JSP 'SingleCount.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css" rel="external nofollow" rel="external nofollow" > --> </head> <body> 已登录. <br> <button id="btnsubmit" name="submit">提交</button> <!-- 引入jQuery --> <script type="text/javascript" src="js/jquery-1.11.3.js"></script> <script type="text/javascript" src="js/jsSubmit.js"></script> </body></html>

写ajax,向后台提交请求

// jsSubmit.js

$(document).ready(function() { // 登录按钮 $("#btnlogin").click(function() { //data,dataType,type,url $.ajax({ url: 'LoginServlet?method=login', type: 'post', data: {username: $("input[name='username']").val()}, // 将用户名传给servlet //dataType:'json', success: function(msg) { // msg为从servlet接收到的返回值 if (msg == 1) { // 接收到后台数据为1,正常登录 window.location.href = "singlecount.jsp"; } }, error:function(){ window.alert("错误!"); } }); }); // 提交按钮 $("#btnsubmit").click(function() { //data,dataType,type,url $.ajax({ url: 'SubmitServlet?method=submit', type: 'post', //dataType:'json', success: function(msg) { // msg为从servlet接收到的返回值 if (msg >= 1) { // 正常 window.alert("提交总数" + msg); } }, error:function(jqXHR){ if(jqXHR.status == 900){ // 900状态码 window.alert("登录状态失效,请重新登录!"); window.location.href = "/OneLogin"; } } }); });});

servlet

这部分有点长,其实主要内容直接看doPost方法就可以了。

// LoginServletpackage servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletConfig;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;@SuppressWarnings("serial")//注解表明什么样的情况下可以访问该内容@WebServlet(urlPatterns={"/LoginServlet"})public class LoginServlet extends HttpServlet { private PrintWriter out; // 输出流 private String user; private String method; private HttpSession session; // 建立一个Map存储session信息,key-用户名,value-session public static Map<String, HttpSession> user_Session = new HashMap<String, HttpSession>(); @Override public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub super.init(config); } @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doDelete(req, resp); } @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 resp.setContentType("text/html"); //语言编码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); out = resp.getWriter(); user = req.getParameter("username"); // 获取index界面username的内容 method = req.getParameter("method"); // 获取方法名 session = req.getSession(); // 获取session switch (method) { case "login": mLogin(); break; default: break; } out.flush(); out.close(); } private void mLogin() { // 按登录按钮调用的方法 // TODO Auto-generated method stub removeUser(user); session.setAttribute("name", user); user_Session.put(user, session); // 新增或覆盖session System.out.println(user_Session); out.println(1); // 返回值1,随意选个值,和前端对应就可以 } /** * 判断是否有重复用户, * 若出现重复用户,踢掉前面登录的用户,即删除其session */ private void removeUser(String user) { if(user_Session.containsKey(user)) user_Session.get(user).invalidate(); }}// SubmitServletpackage servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@SuppressWarnings("serial")//注解表明什么样的情况下可以访问该内容 会在js和web.xml中使用@WebServlet(urlPatterns={"/SubmitServlet"})public class SubmitServlet extends HttpServlet { private PrintWriter out; // 输出流 private String method; private int number = 0; // 计数 @Override public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub super.init(config); } @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doDelete(req, resp); } @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 resp.setContentType("text/html"); //语言编码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); out = resp.getWriter(); method = req.getParameter("method"); // 获取方法名 switch (method) { case "submit": mSubmit(); break; default: break; } out.flush(); out.close(); } private void mSubmit() { // 按提交按钮调用的方法 // TODO Auto-generated method stub number++; out.println(number); }}

过滤器

过滤器的原理这里就不说了,简单来说就是请求要先经过过滤器才能到达servlet,也就是说如果请求不满足要求就无法通过过滤器,这里的要求是要有session。

package filter;import java.io.IOException;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.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebFilter("/SessionFilter")public class SessionFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; String strURL = request.getRequestURL().toString(); // 获取请求路径 // System.out.println(strURL); // 只过滤来自SubmitServlet请求和singlecount.jsp的加载,可以设置成自己想过滤的 // 需要在web.xml中添加<filter> if(strURL.indexOf("SubmitServlet") != -1 || strURL.indexOf("singlecount.jsp") != -1){ if(request.getSession().getAttribute("name") == null){ request.getSession().invalidate(); response.sendError(900, "登录失效,请重新登录!"); // 自定义状态码,session失效 // 900 到ajax的error中处理 return; } else { arg2.doFilter(arg0, arg1); } } else { arg2.doFilter(arg0, arg1); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub }}

配置web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>OneLogin</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>filter.SessionFilter</filter-name> <filter-class>filter.SessionFilter</filter-class> </filter> <filter-mapping> <filter-name>filter.SessionFilter</filter-name> <url-pattern>/singlecount.jsp</url-pattern> <!-- 给界面添加过滤器 --> </filter-mapping> <filter-mapping> <filter-name>filter.SessionFilter</filter-name> <url-pattern>/SubmitServlet</url-pattern> <!-- 给servlet添加过滤器 --> </filter-mapping></web-app>

实现效果

可以使用两个不同的浏览器当两个客户端,或者电脑多就用多台电脑。

相同账号登录时,前面账号再点提交请求就会给出提示,跳转到登录界面

未登录直接进入:http://localhost:8080/OneLogin/singlecount.jsp

如果也想实现跳转效果,在jsSubmit.js的$(document).ready(function() {…}); 前面加入是否有session的判断,没有就给出提示,跳转到登录界面。

总结

以上所述是小编给大家介绍的Java web实现账号单一登录,防止同一账号重复登录,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

本文标题: Java web实现账号单一登录,防止同一账号重复登录(踢人效果)

以上就上有关Javaweb实现账号单一登录,防止同一账号重复登录(踢人效果)的全部内容,学步园全面介绍编程技术、操作系统、数据库、web前端技术等内容。

抱歉!评论已关闭.