前言
HTTP协议是一个“无状态协议”,即客户端和服务器端的本次通信和下一次没有关系,那么我们在通过浏览器进行网页登录时,登录成功后如何访问它的其它页面,浏览器和服务器之间是如何通信的呢?本篇文章介绍了客户端和服务器的交互机制、交互方法和交互过程。
一、Cookie和Session
1.Cookie
之前的文章有讲到过在进行网页登录时浏览器和服务器的交互过程,Cookie在浏览器中,主要作用是存储登录成功时服务器向浏览器响应的sessionId,通过set-cookie字段返回,就像“令牌”一样,有了这个令牌,在访问其他页面的时候只要要带上它就可以访问其他页面了,但是如果它有权限或者失效的时候还是需要进行验证或重新登陆的。
2.会话机制(Session)
服务器需要记录令牌信息以及令牌对应的用户信息,这个就是Session机制所做的工作,它需要记录每一个信息是属于哪个用户的,用户对应哪个令牌,这里就需要用键值对进行存储,而会话的本质就是一个“哈希表”,可key就是令牌的ID(sessionId/token),value就是用户信息。
servlet的session是保存在内存中的,服务器重启的时候session数据就会丢失,但是现在的有些浏览器有时会将这写信息写入你的磁盘中,非常的不好删除。
3.Cookie和Session的区别
(1)Cookie是客户端的机制,Session是服务器端的机制;
(2)Cookie和Session经常配合使用,但是不是必须配合。例如:Cookie中保存的一些数据在客户端,这写数据不一定是用户身份信息,也不一定是SessionId/token;Session中的token/sessionId也不一定非得通过Cookie/set-cookie传递。
4.核心方法
(1)HttpServletRequest的相关方法
方法 | 描述 |
---|---|
HttpSession getSession() | 获取会话,参数为true时,会话不存在时新建会话;参数为false时,会话不存在返回null |
Cookie[] getCookies() | 返回一个数组,包含所有Cookie对象,并且会自动把Cookie中的格式解析成键值对 |
(2)HttpServletResponse的相关方法
方法 | 描述 |
---|---|
void addCookie(Cookie cookie) | 把指定的cookie添加的响应中 |
(3)HttpSession的相关方法
方法 | 描述 |
---|---|
Object getAttribute(String name) | 返回在该会话中名称为name的对象,如果没有则返回null |
void setAttribute(String name,Object value) | 用指定的名称绑定一个对象到session会话 |
boolean isName | 判断当前是否是新建出的会话 |
(4)Cookie的相关方法
方法 | 描述 |
---|---|
String getName() | 返回cookie的名称 |
String getValue() | 获取cookie关联的值 |
void setValue(String newValue) | 设置与cookie关联的值 |
二、实现用户登录
1.功能
(1)构造一个登录页面,包括用户名,密码和登录按钮。
(2)用户通过提交登录向服务器端发送一个post请求,登录的服务器端判断用户名和密码是否正确,正确则跳转到登录成功页面,否则返回登录失败提醒。
(3)跳转到登录成功页面后,页面上有该用户登录了几次等信息。
2.代码实现
login.html(示例):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="userName">
<input type="text" name="passWord">
<input type="submit" value="登录">
</form>
</body>
</html>
login(示例):
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
//获取请求参数
String userName = (String) req.getParameter("userName");
String passWord = (String) req.getParameter("passWord");
if("admin".equals(userName) && "123".equals(passWord)) {
//登录成功
//设置登录次数
//获取session,如果没有则创建新的键值对添加到哈希表中,服务器将sessionId给set-cookie返回
HttpSession httpSession = req.getSession(true);
httpSession.setAttribute("userName",userName);
httpSession.setAttribute("count",0);
//登录成功跳转到index页面
resp.sendRedirect("index");
} else {
//登录失败
resp.getWriter().write("用户名/密码错误,请检查后重新登陆!!!");
return;
}
}
}
index(示例):
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
//获取session
HttpSession session = req.getSession(false);
if(session==null) {
resp.getWriter().write("您尚未登录,请登录后访问!");
resp.sendRedirect("login.html");
}else {
//获取用户名
String userName = (String) session.getAttribute("userName");
//获取上一次登录次数
int count = (int) session.getAttribute("count");
count += 1;
session.setAttribute("count",count);
resp.getWriter().write("<h3>登录成功!欢迎"+userName+"先生/女士,这是您第"+count+"次登录!</h3>");
}
}
}