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

网友投稿 385 2022-12-24


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

实现了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+"/";

%>

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

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

已登录.

写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方法就可以了。

// LoginServlet

package 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 user_Session = new HashMap();

@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");

http://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();

}

}

// SubmitServlet

package 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中添加

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

OneLogin

index.html

index.htm

index.jsp

default.html

default.htm

default.jsp

filter.SessionFilter

filter.SessionFilter

filter.SessionFilter

/singlecount.jsp

filter.SessionFilter

/SubmitServlet

实现效果

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

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

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

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

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Boot集成Spring Cache过程详解
下一篇:Spring Boot 自定义数据源DruidDataSource代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~