目录
一、Cookie 和 Session
1、HttpServletRequest 类中的相关方法
2、HttpServletResponse 类中的相关方法
3、HttpSession 类中的相关方法
4、Cookie 类中的相关方法
二、网页登录
1、约定前后端交互接口
2、编写一个简单的登录页面
3、编写一个Servlet 来处理这个登录请求。
4、编写服务器端返回主页的逻辑
5、效果展示
一、Cookie 和 Session
在请求响应(header)中介绍过。HTTP详细介绍
在Servet 中,对于 Cookie 和 Session 都有很好的支持,因此就可以通过这些API来完成会话管理的操作。以下介绍几个核心方法。
1、HttpServletRequest 类中的相关方法
方法 | 描述 |
HttpSession getSession() | 在服务器中获取会话。 参数若为 true,则当不存在会话时新建会话; 参数若为false,则当不存在会话时返回 null。 |
Cookie[] getCookies() | 返回一个数组,包含客户端发送该请求的所有 Cookie 对象。 会自动把 Cookie 中的格式解析成键值对。 |
在调用 getSession 时具体做的事情:
(1)创建会话
首先先获取到请求中 cookie 里面的 session 字段(相当于会话的身份标识),判定这个 session 是否在当前服务器上存在,如果不存在,则进入创建会话逻辑。
创建会话,会创建一个 HttpSession 对象,并且生成一个 session(是一个很长的数字,通常用十六进制来表示,能够保证唯一性), 接下来就会把这个 session 作为 key,把这个 HttpSession 对象作为 value ,把这个键值对给保存到 服务器内存 的一个 “ 哈希表 ” 这样的结构中。(实际的实现不一定真是哈希表,但是一定是类似的能存储键值对的结构,并且这个数据是在内存中的)
(2)获取会话
先获取到请求中的 cookie 里面的 session 字段(也就是会话的身份标识),判定这个 session 是否在当前服务器上存在(也就是在这个哈希表中是否有),如果有,就直接查询出这个 HttpSession 对象,并通过返回值返回。
getCookie :
返回值是一个 Cookie 类型的数组,每个元素是一个 Cookie 对象,每个 Cookie 对象有包含了两个属性 name 和 value 。(还是键值对)
Http 请求中的 cookie 字段就是按键值对的方式在组织的,这里的键值对使用 ;来分割多个键值对,使用 = 来分割键和值。 这些键值对都会在请求中通过 cookie 字段传给服务器,服务器收到请求后,就会进行解析,解析成上述看到的 Cokkie[] 这样的形式。
2、HttpServletResponse 类中的相关方法
方法 | 描述 |
void addCookie(Cookie cookie) | 把指定的 cookie 添加到响应中 |
响应中就可以根据这个 addCookie 这个方法,来添加一个 Cookie 信息到响应中。这里添加进来的键值对,就会作为 HTTP 响应中的 Set-Cookie 字段来表示。
3、HttpSession 类中的相关方法
一个 HttpSession 对象里包含多个键值对(key:String;value:Object),我们可以往 HttpSession 中存任何我们需要的信息。
方法 | 描述 |
Object getAtttribute(String name) | 该方法返回在该 session 会话中具有指定名称的对象。 如果没有指定名称的对象,则返回 null (取键值对) |
void setAttribute(String name, Object value) | 该方法使用指定的名称绑定一个对象到该 session 对象 (存键值对) |
boolean isNew() | 判断当前是否是新创建出的会话 |
4、Cookie 类中的相关方法
每个Cookie 对象就是一个键值对。
方法 | 描述 |
String getName() | 该方法返回 cookie 的名称。 名称在创建后不能改变(这个值是 Set-Cookie 字段设置给浏览器的) |
String getValue() | 该方法获取与 cookie 关联的值 |
void setValue(String newValue) | 该方法设置与 cookie 关联的值 |
Cookie 这里是可以保存任意自定制的键值对的。
如果是一般的键值对,直接通过 getCookies 来获取。
如果是特殊的键值对(表示 session 的键值对),不需要使用 getCookies,直接使用 getSession 就自动帮我们从 Cookie 中取 session 了。
二、网页登录
先创建 Servlet 项目,并创建好目录。
1、约定前后端交互接口
有两组交互:登录,获取主页
登录的交互:
请求:
POST/login HTTP/1.1
Content-Type:application/x-www-form-urlencoded
username=zhangsan&password=123
响应:
HTTP/1.1 302
Location:index
获取主页的交互:
请求:
GET/index HTTP/1.1
响应:
HTTP/1.1 200 OK
Content-Type:text/html
[ body 中时一个简单的 html 片段,直接有浏览器进行展示]
2、编写一个简单的登录页面
使用 form 表达来构造post请求。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>登录</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
3、编写一个Servlet 来处理这个登录请求。
loginServlet.java:
处理第一个登录交互的请求。保证跳转到主页(index)的时候,服务器要能够获取到当前用户的身份信息,因此要创建好一个 Session 对象,并填入身份信息。
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;
/**
* Created with IntelliJ IDEA.
* Description:实现登录页面
* User: WangWZ
* Date: 2023-05-05
* Time: 15:57
*/
@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");
//判定用户名和密码是否正确
//正常来说这个判定操作是要放在数据库中进行存取的
//此处为了简单,就直接在代码里写死了,假设有效的用户名和密码是:“zhangsan” 和 “123”
if ("zhangsan".equals(username) && "123".equals(password)) {
//登录成功!
//创建会话,并保存必要的身份信息
HttpSession httpSession = req.getSession(true);
//往会话中存储键值对,必要的身份信息
httpSession.setAttribute("username",username);
httpSession.setAttribute("count",0);
resp.sendRedirect("index");
} else {
//登录失败!
resp.getWriter().Writer("登录失败!");
}
}
}
4、编写服务器端返回主页的逻辑
IndexServlet.java:
第二次交互。
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;
/**
* Created with IntelliJ IDEA.
* Description:
* User: WangWZ
* Date: 2023-05-05
* Time: 17:25
*/
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//返回一个主页(主页就是一个简单的 html 片段)
//此处需要得到用户名是啥,从 HttpSession 中就能拿到
//此处的 getSession 的参数必须是 false,前面在登录的过程中,已经创建过会话了,此处要直接获取到之前的会话
HttpSession session = req.getSession(false);
String username = (String) session.getAttribute("username");
Integer count = (Integer) session.getAttribute("count");
count += 1;
session.setAttribute("count",count);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3>欢迎你 " + username +"这是你访问的第 " + count + "次 </h3>");
}
}
5、效果展示
点击页面刷新
第一次交互:
请求
响应
第二次交互:
请求
响应