Servlet中的HttpServletRequest类方法中提供两个方法:
方法 | 描述 |
---|---|
HttpSession getSession() | 在服务器中获取会话.参数如果为true,则当不存在会话时新建会话;参数如果为 false,则当不存在会话时返回null |
Cookie[] getCookies() | 返回一个数据,包含客户端发送该请求所有的Cookie对象,自动把Cookie格式转化为键值对 |
在调用getSession的时候需要做的事情如下:
- 首先获取请求中Cookie中的sessionId字段。之后判断这个这个字段在服务器上是否存在,如果不存在的话可以选择创建会话或者直接拒绝请求。
- 创建会话,会创建一个HttpSession对象,并且生成一个sessionId(长数字,一般是16进制,且是唯一的)
- 把这个sessionId作为key,HttpSession对象作为value,把这个键值对保存到服务器内存的一个类似于哈希表的结构中。(内存中,服务器重启会丢失会话数据)
- 服务器返回一个Http响应,把SessionId通过 addCookie(Cookie cookie)来设置Set-Cookie字段返回给浏览器,浏览器保存这个sessionId到Cookie中。
获取会话:
- 先获取请求cookie字段的sessionId(会话身份标识)
- 判断sessionId是否在服务器内存上存在。有的话查询出HttpSession对象,并且返回回去。
HttpSession对象:
这个对象也是键值对结构,可以向HttpSession对象中储存数据。HttpSession对象内部的每个键值对称为属性(Attribute)
HttpSession对象提供了两个方法,getAttribute和setAttribute来操作内部的键值对
eg:网页登录练习
需求模拟:
- 用户点击登录后,将请求发送到服务器,服务器正常处理登录请求后,返回302响应。因为跳转到主页时服务器需要获取当前用户的身份信息,这时候就需要创建好一个Session供后面来使用,并且向Session中填写必要的身份信息。
- 浏览器重新请求向服务器请求主页,服务器返回主页用户的信息
规定前后端交互接口:
- 登录交互:
请求:
POST /login HTTP/1.1
使用form表单形式
Content-Type:application/x-www-form-urlencoded
空行
username=xxxxx&password=xxxxx
响应:
HTTP/1.1 302
Location:index
- 获取主页交互
请求:
GET /index HTTP/1.1
响应:
HTTP/1.1 200 OK
Content-Type:xxxx
登录页面:
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<style>
.log {
width: 100%;
height: calc(100% - 50px);
display: flex;
align-items: center;
justify-content: center;
}
.logdiv {
width: 350px;
height: 350px;
/* background: red; */
background-color: rgba(245, 227, 227, 0.8);
border-radius: 10px;
}
.logdiv .row {
height: 50px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.logdiv .row span {
display: block;
width: 70px;
font-weight: 700;
}
.logdiv h3 {
text-align: center;
padding: 20px 0;
font-size: 20px;
}
</style>
<body>
<div class="log">
<div class="logdiv">
<h3>登录</h3>
<form action="login" method="post">
<div class="row">
<span>用户名:</span>
<input type="text" name="username"><br>
</div>
<div class="row">
<span>密码:</span>
<input type="password" name="password"><br>
</div>
<div class="row" id="sub"><input type="submit" value="登录"></div>
</form>
</div>
</div>
</body>
</html>
登录后端代码:
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 java.io.IOException;
@WebServlet("/login")
public class LogInServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + " " + password);
//跳过数据库读取用户数据阶段
if ("root".equals(username) && "000000".equals(password)) {
//通过登录验证,保存用户信息
HttpSession httpSession = req.getSession(true);
//向会话中存储信息
httpSession.setAttribute("username", username);
httpSession.setAttribute("count", 0);
//302跳转
resp.sendRedirect("index");
} else {
resp.getWriter().write("log password or username fail");
}
}
}
第二次请求服务器
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 java.io.IOException;
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//返回主页
//从session中获取用户名
HttpSession httpSession = req.getSession(false);//此处一定存在session会话
String username = (String) httpSession.getAttribute("username");
Integer count = (Integer) httpSession.getAttribute("count");
count += 1;
//将访问次数写回session中
httpSession.setAttribute("count", count);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3>" + username + " 访问次数: " + count + "</h3>");
}
}
抓包如下图:
登录时,服务器发回302跳转,并设置cookie
跳转后,客户端继续请求服务器,服务器根据session构造主页并返回