JavaWeb---Servlet监听器实现单一登陆
1. 监听器实现单一登录
对session有过一点了解的人员应该都知道,在java中session的默认的销毁时间是大于或等于30分钟,如果你对session的生命周期不做任何配置的话,按照上面的设想,那么只要用户登陆上之后,这时该用户的状态设置为1,在大于30分钟的时间内如果该用户没有向服务器端发起任何请求的话,那么这个session就会被销毁掉,注意了,这时session生命周期结束以后自动销毁的,并不是用户点退出按钮来销毁的,那这样就不能触发用户退出事件,那这个用户的状态你就没法改变了,也就是说,如果按照上面的设想,你想想,如果遇到这样的情况,那这个用户的状态就一直都是1了,那这个用户以后再想登陆就再也登陆不上了。很明显,这样是不对的。
使用Servlet监听器实现监听用户会话状态,从而自动去改变用户的登录状态
a.对登陆进行判断
<%
request.setCharacterEncoding("utf-8");
out.print("登陆处理页面:");
//1.取到表单提交过来的数据
Stringname = request.getParameter("name");
Stringpwd = request.getParameter("pwd");
//2.加载jdbc驱动
Class.forName("com.mysql.jdbc.Driver");
//3.使用驱动管理类创建链接对象
Stringurl = "jdbc:mysql://127.0.0.1:3306/news?user=root&password=root";
Connectionconn = DriverManager.getConnection(url);
//4.通过连接对象创建执行对象
Statementstm = conn.createStatement();
//5.通过命令执行对象执行sql脚本
Stringsql = "select * from users where uname ="" + name
+"" and upwd = "" + pwd + """;
//6.执行查询语句得到结果集
ResultSetrs = stm.executeQuery(sql);
//加判断从session中和登陆的数据做对比
ServletContextcontext = getServletContext();
Map<String,String> us = (Map<String,String>)context.getAttribute("users");
//Boolean 状态 找到用户则设置为ture
boolean falg = false;
if(us!=null){
//遍历Map集合中的Key值
for(String k:us.keySet()){
//判断us中这个Map是否存储了登陆用户
if(us.get(k).equals(name)){
//存在该用户
falg=true;
%>
<script type="text/javascript">
alert("用户" + name + "已经登陆,不能重复登陆!");
//在当前页面跳转
open("admin.jsp", "_self");
<%break;
}
}
}
//7.判断状态和结果集中是否有数据
if(!falg&&rs.next()) {
//将id:name 做键值映射存储到Session
String Id= rs.getString(1);
us.put(Id,name);
//---------_________________________--
context.setAttribute("NAME", name);
if(name.equals("admin")){
response.sendRedirect("admin.jsp");
}%>
<script type="text/javascript">
alert(name + "登陆成功!");
//在当前页面跳转
open("admin.jsp", "_self");
</script>
<%
}else{
%>
<script type="text/javascript">
alert("登陆失败!");
open("index.jsp", "_self");
</script>
<%
}
//8.关闭资源
rs.close();
stm.close();
conn.close();
//9.跳转到首页 getRequestDispatcher 相当于forword跳转动作
//request.getRequestDispatcher("../index.jsp");
%>
b.手动注销
<%
//取出name数据
ServletContext context = getServletContext();
String name = (String) context.getAttribute("NAME");
//再取出map数据
Map<String,String> us =(Map<String,String>)context.getAttribute(name);
if(us!=null){
//遍历Map集合中的Key值
for(String k:us.keySet()){
//判断us中这个Map是否存储了登陆用户
if(us.get(k).equals(name)){
//存在该用户则去掉该用户
us.remove(k);
}
}
}
//把移除后的数据设置进入session中
context.setAttribute("users",us);
context.removeAttribute("NAME");
response.sendRedirect("index.jsp");
%>
c.会话自动注销 将执行的方法
/**
* 会话注销将执行的方法
*/
@Override
publicvoidsessionDestroyed(HttpSessionEvent sev) {
System.out.println("会话注销");
// 得到session对象
HttpSessionsession = sev.getSession();
// 从session对象中得到context对象
ServletContextcontext = session.getServletContext();
// 取出name数据
Stringname = (String) context.getAttribute("NAME");
// 再取出map数据
Map<String,String> us = (Map<String, String>) context
.getAttribute(name);
if (us != null) {
// 遍历Map集合中的Key值
for (String k :us.keySet()) {
// 判断us中这个Map是否存储了登陆用户
if(us.get(k).equals(name)) {
// 存在该用户则去掉该用户
us.remove(k);
break;
}
}
// 把移除后的数据设置进入session中
context.setAttribute("users",us);
}