官方你网站建设策略,深圳网站建设选哪家好,网站建设合同书下载,上海小企业网站建设平台目录 一、 HTTP协议
1.1 为什么HTTP协议是无状态的#xff1f;
1.2 在HTTP协议中流式传输和分块传输编码的区别
二、Cookie和Session
2.1 Cookie
2.2 Session
2.3 Cookie和Session的区别
三、servlet中与Cookie和Session相关的API
3.1 HttpServletRequest 类中的相关方…目录 一、 HTTP协议
1.1 为什么HTTP协议是无状态的
1.2 在HTTP协议中流式传输和分块传输编码的区别
二、Cookie和Session
2.1 Cookie
2.2 Session
2.3 Cookie和Session的区别
三、servlet中与Cookie和Session相关的API
3.1 HttpServletRequest 类中的相关方法
3.2 HttpServletResponse 类中的相关方法
3.3 HttpSession 类中的相关方法
3.4 Cookie 类中的相关方法
四、实现模拟登录流程 一、 HTTP协议
我们知道HTTP协议是一种无状态协议这意味着每个HTTP请求都是独立的服务器不会记住之前的任何请求也不会记录当前请求与之前请求的关系。每个请求都是独立的、不相关的服务器不会保留任何有关请求或响应的信息也不会保存客户端的状态。 1.1 为什么HTTP协议是无状态的 这是由于HTTP协议的工作机制决定的客户端向服务器发起请求服务器响应请求并返回相应的数据。在请求完成后服务器会立即关闭连接不会再保持连接状态下一次请求需要重新建立连接。因此服务器无法保存客户端的状态信息。
为了解决这个问题Web应用程序通常使用一些技术来维护客户端状态例如Cookie和Session。这些技术在客户端和服务器之间传递状态信息使得应用程序能够跟踪每个客户端的状态实现有状态的应用程序。 需要注意的是。虽然HTTP协议为无状态协议但是与HTTP支持长连接不冲突。 长连接也称为持久连接是一种HTTP/1.1协议引入的技术它允许客户端和服务器在一个TCP连接上发送多个HTTP请求和响应而不需要为每个请求/响应都建立一个新的TCP连接。这种技术可以显著减少网络连接的建立和关闭开销提高网络传输效率同时也能够更好地支持HTTP协议的特性如流式传输和分块传输编码等。
在长连接中客户端和服务器之间的TCP连接在一个HTTP请求/响应完成后不会立即关闭而是继续保持连接状态等待下一个HTTP请求/响应。这样当客户端发送下一个HTTP请求时可以直接利用之前的TCP连接不需要再进行TCP握手和挥手等操作从而节省了网络资源和时间。
因此虽然HTTP协议是无状态的但是通过使用长连接技术可以在保持无状态的前提下提高HTTP协议的效率和性能。需要注意的是长连接需要服务器和客户端都支持否则无法建立长连接。同时长连接也可能会导致资源占用问题因此需要合理使用和配置。
以下为浏览器请求BIng主页的抓包信息Connectionkeep-alive就为长连接的意思
在HTTP/1.1中如果客户端请求头中没有明确指定Connection头字段那么服务器会默认使用长连接即保持TCP连接处于打开状态直到客户端或服务器明确要求关闭连接为止。这种方式可以减少每次请求和响应时建立和关闭TCP连接的开销提高网络传输效率和性能。但需要注意的是长连接并不是在所有情况下都适用有时候也需要根据实际情况关闭连接。 1.2 在HTTP协议中流式传输和分块传输编码的区别 流式传输和分块传输编码都是HTTP协议中用于数据传输的技术它们的区别如下 数据分割方式不同流式传输是将响应数据如HTMLJSON等按照一定的块大小进行分割逐步发送到客户端而分块传输编码是将数据分成若干个块Chunk每个块有独立的长度信息和数据内容使用分块传输编码方式将数据分成多个块进行传输每个块之间用一个CRLF回车换行分隔符分开。 响应方式不同流式传输是一次性发送响应数据客户端在接收到第一个数据块时就可以开始处理而分块传输编码则是将响应数据分成多个块逐个发送客户端需要在接收完所有块后再进行处理。 大小控制不同流式传输中每个数据块的大小是固定的由服务器决定而分块传输编码中每个块的大小是不固定的客户端需要通过读取长度信息来确定每个块的大小。 读取速度应用场景不同流式传输是在客户端接收到第一个数据块时就可以开始处理而不必等待整个响应数据全部接收完毕。这种方式可以减少客户端等待时间提高响应速度。流式传输常用于需要实时更新的数据场景如股票行情、新闻快讯等。而分块传输编码客户端接收到每个块后会先读取块的长度信息再读取对应长度的数据内容。这种方式可以避免一次性传输大量数据造成的网络拥塞和连接中断并且可以让客户端在接收到部分数据时就开始处理从而提高传输效率和响应速度。
总之流式传输和分块传输编码都可以提高HTTP数据传输的效率和响应速度但应根据具体的场景和需求进行选择和使用。流式传输适用于需要实时更新的数据场景如股票行情、新闻快讯等而分块传输编码适用于需要传输大文件的场景能够避免一次性传输造成的网络拥塞和连接中断。
二、Cookie和Session
2.1 Cookie
上面我们说到由于HTTP是无状态的所以需要引入Cookie来解决这一问题。
Cookie允许服务器在客户端上存储少量的数据例如用户的身份偏好购物车信息等。以便在之后的HTTP请求中将该数据发送回服务器通过Cookie服务器可以识别和跟踪用户的身份和状态从而提供更加个性化和定制化的服务。 回顾以下Cookie是什么从哪里来发送到哪去存储在哪 是什么Cookie是一种由服务器发送到客户端的小型数据文件它包含了有关用户和网站之间的交互信息以及有关用户的偏好和状态信息,从哪里来当服务器想要在客户端上创建或者添加一个新的Cookie时候会将Set-Cookie字段添加到HTTP响应头中告诉客户端应该如何创建或跟新CookieSet-Cookie中是由开发者自己定义的键值对。发送到哪去客户端在接收到带有Set-Cookie字段的HTTP响应时会解析该字段并根据其中的信息在本地创建或更新对应的Cookie。之后在该客户端向同一服务器发出HTTP请求时该Cookie信息会被自动添加到HTTP请求头中从而让服务器能够识别并跟踪用户的身份和状态。存储在哪在客户端Cookie通常存储在Web浏览器所在的硬盘中浏览器会根据域名来分别存储。
2.2 Session
Session会话是Web应用程序中的一个概念它指的是一系列相关的HTTP请求和响应通常用于在客户端和服务器之间维护一些状态信息。在一个会话中服务器会创建一个唯一的Session ID会话标识符并将该Session ID发送给客户端浏览器。客户端在之后的每个HTTP请求中都会携带该Session ID以便服务器能够识别并跟踪该客户端的身份和状态。 为了加深理解我们来看一组登录流程 Session通常是基于Cookie实现的。具体来说当服务器创建一个新的Session时它会在响应头中添加一个Set-Cookie字段其中包含了一个名为SESSIONID的Cookie值该值就是新创建的Session ID。客户端在收到该响应时会将该Cookie值保存在浏览器中并在之后的每个HTTP请求中发送回服务器。服务器在接收到每个HTTP请求时都会检查该请求中是否包含了有效的Session ID如果存在则说明该请求属于某个已经创建的Session服务器就可以根据该Session ID来识别和跟踪客户端的身份和状态。
需要注意的是Cookie是有存储期限的越敏感的网站存储期限越短。
2.3 Cookie和Session的区别
Cookie和Session是Web开发中常用的两种技术用于在服务器和客户端之间保持状态信息。它们的区别如下 存储位置不同Cookie是存储在客户端的浏览器中的文本文件而Session是存储在服务器端的内存中或者数据库中的键值对。 安全性不同由于Cookie是存储在客户端中的所以存在被窃取或者篡改的风险。而Session存储在服务器端相对来说更加安全。 存储容量不同Cookie的存储容量较小通常为4KB左右而Session的存储容量可以比较大但会占用服务器的内存或者存储资源。 生命周期不同Cookie可以设置过期时间可以长期保存在客户端的浏览器中而Session在用户关闭浏览器或者超过一定时间后会自动销毁。 使用方式不同Cookie是通过在服务器端发送HTTP响应头来设置的客户端的浏览器会自动保存Cookie下一次请求时会自动发送Cookie到服务器端。而Session需要在服务器端通过某种方式生成Session ID并将Session ID存储在Cookie中或者URL参数中客户端浏览器会将Session ID发送到服务器端服务器根据Session ID来获取Session数据。
综上所述Cookie和Session都可以用于在服务器和客户端之间保持状态信息但它们的应用场景和特点有所不同具体使用哪种技术要根据实际需求和安全要求来决定。
三、servlet中与Cookie和Session相关的API
3.1 HttpServletRequest 类中的相关方法
方法描述HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果 为 false, 则当不存在会话时返回 nullCookie[] getCookies()返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把 Cookie 中的格式解析成键值对.
3.2 HttpServletResponse 类中的相关方法
方法描述void addCookie(Cookie cookie)把指定的 cookie 添加到响应中.
3.3 HttpSession 类中的相关方法
方法描述Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象如果没 有指定名称的对象则返回 null.void setAttribute(String name, Object value)该方法使用指定的名称绑定一个对象到该 session 会话boolean isNew()判定当前是否是新创建出的会话
3.4 Cookie 类中的相关方法
每个 Cookie 对象就是一个键值对
方法描述String getName()该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 Set Cooke 字段设置给浏览器的)String getValue()该方法获取与 cookie 关联的值void setValue(String newValue)该方法设置与 cookie 关联的值。
HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了一个 Cookie对象.通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.
四、实现模拟登录流程
第一步约定前后端接口。 我们需要实现两套交互逻辑一是登录跳转二是获取主页。 登录跳转约定 约定使用POST请求响应采用302重定向。
package login;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: 86136* Date: 2023-04-01* Time: 18:53*/
WebServlet(/loginServlet)
public class LoginServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username req.getParameter(username);String password req.getParameter(password);//因为这里我们主要是演示Cookie和Session所以为了简化流程并不将用户名和密码//存入到数据库中而是直接定死。约定用户名合法为 Jay 和 Lin//密码合法为123。if(!username.equals(Jay) !username.equals(Lin)) {//登录失败System.out.println(用户名错误);resp.sendRedirect(login.html);return;}if (!password.equals(123)) {//登录失败System.out.println(密码错误);resp.sendRedirect(login.html);return;}//登录成功//1.创建一个会话HttpSession session req.getSession(true);//2.把当前的用户名保存在会话中//void setAttribute(String var1, Object var2);session.setAttribute(username,username);//初始情况下设置登录次数session.setAttribute(count,0);//3.重定向到主页resp.sendRedirect(indexServlet);}
}分析
其中的getSessiontrue判定当前请求是否已经有对应的会话拿着来自客户端的请求中Cookie里的sessionId查一下如果sessionId不存在或者没有被查到那么就创建一个新的会话并插入到哈希表中。如果查到了就直接返回查到的结果。
创建新的会话的流程如下构造一个HttpSession对象构造唯一的sessionId把这个键值对插入到哈希表中最后把sessionId设置到响应报文的Set-Cookie字段中有服务器发送给浏览器。 获取主页约定 采用GET请求响应返回一个页面:
package login;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(/indexServlet)
public class IndexServlet extends HttpServlet {//因为通过浏览器是通过重定向来发送请求的所以以下为doGetOverrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//需要先判定用户的登录状态//如果用户没有登录要求先登录如果登录了则根据 会话 中的用户名来显示到页面上//这个操作不会触发会话的创建HttpSession session req.getSession(false);if (session null) {//未登录状态System.out.println(用户未登录);}//已经登录,取出会话信息String username (String) session.getAttribute(username);Integer cnt (Integer) session.getAttribute(count);//访问次数加1cnt;//写回到会话中session.setAttribute(count,cnt);//构造页面resp.setContentType(text/html; charsetutf8);resp.getWriter().write(h3欢迎 username /h3 h4这个页面已经被访问了cnt次/h4);}
}第二步编写前端交互页面 我们的重点是来学习登录的逻辑因此登录的界面不需要很好看很复杂只要能够有两个输入框和一个提交按钮让我们输入账号密码就行。目标页面如下 前面我们约定了登录的跳转采用post请求由于场景很简单我们直接使用form表单构造post请求就可以了:
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodyform actionloginServlet methodpostinput typetext nameusernamebrinput typepassword namepasswordbrinput typesubmit name提交/form
/body
/html
其中input标签的name属性就对应键值对的key输入的内容就对应键值对的value。
效果演示 下面利用抓包结果来进一步加深理解 第一次交互 请求部分注意第一次请求是没有Cookie的。 服务器返回给登录界面的响应部分 第二次交互 在登录状态下主页向服务器发起访问请求 这个带有Cookie的get请求到达服务器的时候Servlet会在getSession方法中根据sessionId来查询HttpSession对象 由于sessionId查的到于是就返回信息。 服务器返回给浏览器的响应部分