很多系统对于某些关键的功能需要登录后才能使用,比如支付、下载、评论等。服务器如何记忆用户是否登录?
常识:http是无状态协议,
无状态如何理解?
http是基于request/response模式,
session也是jsp中的一个内置对象。
session的原理:
用户登录时会在服务器内部开辟一块空间,专门存储该用户的session信息,不同的用户拥有不同的session空间,它们用sessionId来标识,该id在用户访问过程中会以cookie的形式写到客户端,客户端下次再访问时,会携带sessionId,服务器根据id查找session信息,从而判断是否登录过。
需求:使用session记忆用户登录,如果没有登录,则强制登录。
(1)准备User用户类
package com.njwbhz.entity;
public class User {
private String userName;
private String pwd;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + ''' +
", pwd='" + pwd + ''' +
'}';
}
}
(2)修改doLogin.jsp
<%@ page import="com.njwbhz.entity.User" %><%--
Created by IntelliJ IDEA.
User: Fairy
Date: 2022/5/16
Time: 22:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
doLogin
<%--处理登录请求--%>
<%
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
//查询数据库
//模拟手段 假定数据库中存在用户名为sa,密码:1234
if ("sa".equals(userName) && "1234".equals(pwd)) {//登陆成功
//跳转到user/home.jsp
//response对象
//重定向
// response.sendRedirect("home.jsp?userName=" + userName);
//转发
//获取一个转发器 再转发
// request.getRequestDispatcher("home.jsp").forward(request , response);
//构造一个cookie
//Cookie(String name , String value)
// Cookie cookie = new Cookie("userName" , userName);
//设置cookie的有效期
// cookie.setMaxAge(1000 * 60 * 60);//一个小时
//把cookie写到客户端
// response.addCookie(cookie);//跟着response一起写到客户端
User user = new User();
user.setUserName(userName);
user.setPwd(pwd);
//在服务器中开辟session空间,并保存用户数据
session.setAttribute("user" , user);
//获取session的id,把id写到客户端——>内部自动完成
response.sendRedirect("home.jsp");
}
%>
(3)home.jsp
<%@ page import="com.njwbhz.entity.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
首页
<%
//通过request获取cookie数据
Cookie [] cookies = request.getCookies();
String userName = "";
//判断用户是否登录
//读取客户端的sessionId,服务器中查找session对象,如果有:登录,如果没有:没有登陆
//自动完成
User user = (User) session.getAttribute("user");
if (user != null) {//已经登录了
out.write("欢迎" + user.getUserName() + "");
} else {
%>
<%
}
%>
欢迎<%=userName%>登录
(4)测试
停止服务器
启动服务器
打开浏览器直接访问home.jsp
正常登录
浏览器不全关闭,重新开窗口,直接访问home.jsp
Session说明:
(1)把浏览器全部关闭后,再打开浏览器,直接访问home.jsp
不认识,F12查看session发现sessionId丢失了
其实session内部就是使用临时cookie技术
(2)session的有效期设置
多种设置方式:
1.硬编码
测试:
停止服务器
启动服务器
访问home.jsp ----》强制登录
登录成功后,不关闭浏览器,重新开窗口,直接访问home.jsp--->能访问
过1个小时之后,再访问home.jsp ---》不能访问
用途:防止用户长时间不使用系统,session数据在内存里仍然占据着,设置有效期就能有效期的保护内存资源。
2.采用配置,修改工程下的wexml文件
删除代码中的超时设置
3.修改tomcat的web.xml
结论:硬编码的方式肯定不用,
如果配置tomcat中的超时,则该服务器下的所有应用都有效。
如果配置各自应用下的超时,只对该应用有效。
(3)当浏览器全部关闭后,服务器不再识别该用户是否登录
服务器中的用户session存在吗?
session内部就是使用临时cookie技术,浏览器的临时cookie——>jsessionid不在了,所以再次访问时,找不到对应的session。但是session空间仍然存在,这样的session就没有了,清除服务器中无用的session空间。
(4)有些系统带退出功能
session.invalidate();——>让session失效,背后会清除当前用户的整个session空间
session.removeAttribute():清除session中某个数据,但是session空间仍然存在。
(5)session存储数据的范围要比request大,牵涉到作用域问题。



