Servlet 是Java Web 开发的规范。任何一个mvc的框架都是servlet发展来的。SpringMVC使用DispatcherServlet拦截所有API请求,自定义注解进行URL匹配。
1.Web Client 向Servlet容器(Tomcat)发出Http请求。
2.Servlet容器接收Web Client的请求。
3.Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
4.Servlet容器创建一个HttpResponse对象。
5.Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。
6.HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
7.HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
8.Servlet容器把HttpServlet的响应结果传给Web Client。
1.Servlet
Servlet接口Servlet定义了 Servlet 的主要方法
2.GenericServlet
是一个抽象类,实现了 Servlet 接口,对 init()、destroy()、service() 提供了默认实现。主要工作有
1.将 init() 中的 ServletConfig 赋给一个类级变量,可以由 getServletConfig 获得;
2.为 Servlet 所有方法提供默认实现;
3.可以直接调用 ServletConfig 中的方法;
3.HttpServlet
HttpServlet 是 Servlet 接口的实现类,主要封装了 HTTP 请求的方法。
Cookie 客户端会话
Cookie用键值对包含了name、value信息(保存的是字符串信息)。
会话级别 Cookie(默认):Cookie 保存到浏览器的内存中,浏览器关闭则 Cookie 失效。
持久的 Cookie:Cookie 以文本文件的形式保存到硬盘上。
Cookie 的缺点
1.在 HTTP 请求中,Cookie 是明文传递的,容易泄露用户信息,安全性不高。
2.浏览器可以禁用 Cookie,一旦被禁用,Cookie 将无法正常工作。
3.Cookie 对象中只能设置文本(字符串)信息。
4.客户端浏览器保存 Cookie 的数量和长度是有限制的。
// 从 request 获取所有的cookie
Cookie[] cookies = request.getCookies();
// 创建 cookie
Cookie cookie = new Cookie("lastTime", "");
// 设置有效时间为0,删除cookie
cookie.setMaxAge(0);
// 设置有效路径,必须与要删除的Cookie的路径一致
cookie.setPath("/sessionDemo");
// 回写
response.addCookie(cookie);
// 重定向到页面
response.sendRedirect("/user/userIndex");
Session 服务端会话
默认过期时间为30分钟
1.客户端第一次请求会话对象时,服务器会创建一个 Session 对象,并为该 Session 对象分配一个唯一的 SessionID。
2.服务器将 SessionID 以 Cookie(Cookie 名称为:“JSESSIONID”,值为 SessionID 的值)的形式发送给客户端浏览器。
3.客户端浏览器再次发送 HTTP 请求时,会将携带 SessionID 的 Cookie 随请求一起发送给服务器。
4.服务器从请求中读取 SessionID,然后根据 SessionID 找到对应的 Session 对象。
// 获取session对象
HttpSession session=request.getSession();
// 设置会话的过期时间 单位为秒
session.setMaxInactiveInterval(100);
public class MyServlet implements Servlet {
//Servlet 实例被创建后,调用 init() 方法进行初始化,该方法只能被调用一次
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
//返回 ServletConfig 对象,该对象包含了 Servlet 的初始化参数
@Override
public ServletConfig getServletConfig() {
return null;
}
//每次请求,都会调用一次 service() 方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//设置字符集
servletResponse.setContentType("text/html;charset=UTF-8");
//使用PrintWriter.write()方法向前台页面输出内容
PrintWriter writer = servletResponse.getWriter();
writer.write("编程帮欢迎您的到来,网址: www.biancheng.net");
writer.close();
}
//返回关于 Servlet 的信息,例如作者、版本、版权等
@Override
public String getServletInfo() {
return null;
}
//Servelet 被销毁时调用
@Override
public void destroy() {
}
}
Filter(过滤器)是JavaEE的规范。可以对URL进行拦截,拦截之后在过滤器中进行相应的处理/判断。
应用场景: 1.权限检查; 2.日记操作; 3.事务管理...等。
自定义的 Filter
@Component
public class MyFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(MyFilter.class);
@Override
public void init(FilterConfig filterConfig) {
logger.info("初始化过滤器:", filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//对请求进行预处理
logger.info("过滤器开始对请求进行预处理:");
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUri = request.getRequestURI();
System.out.println("请求的接口为:" + requestUri);
long startTime = System.currentTimeMillis();
//通过 doFilter 方法实现过滤功能
filterChain.doFilter(servletRequest, servletResponse);
// 上面的 doFilter 方法执行结束后用户的请求已经返回
long endTime = System.currentTimeMillis();
System.out.println("该用户的请求已经处理完毕,请求花费的时间为:" + (endTime - startTime));
}
@Override
public void destroy() {
logger.info("销毁过滤器");
}
}
无状态、无连接
持久连接、请求管道化、增加缓存处理、增加Host字段、支持断点传输等
http的请求格式
1.请求行 GET为请求类型,/mix/76.html?name=kelvin&password=123456为要访问的资源,HTTP/1.1是协议版本 2.请求头部 从第二行起为请求头部,Host指出请求的目的地(主机域名);User-Agent是客户端的信息,它是检测浏览器类型的重要信息,由浏览器定义,并且在每个请求中自动发送。 3.空行 请求头后面必须有一个空行 4.请求数据 请求的数据也叫请求体。
GET /favicon.ico HTTP/1.1
Host: 121.40.62.167:9999
Connection: keep-alive
User-Agent: Mozilla/5.0 (windows NT 10.0: Win64: x64) Applewebkit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 safari/537.36 Edg/103.0.1264 .49
Accept: image/webp, image/apng, image/svg+xml, image/*, */*;q=0.8Referer: http://xxxxxxx:9999/Accept-Encoding: gzip, deflate
Accept-Language: zh-CN, zh:q=0.9, en: q=0.8, en-GB;q=0.7, en-US;q=0.6
Cookie: order=id20desc; serverType=nginx: pro_end=-1: 1td_end=-1: memsize=3748; bt_user_info=87B822status2283Atrue82C22msg2283A8228u83B78u5 3D68u6210%u529F82182282C22data223A87B822username 223A822183****78392287D87D: backup_path=/www/backup: sites_path=/www/wwwroot; site_model=ava: config-tab=1: 9273e354ba8b7935dcc533ebc06536a1=ab3ce455-9457-49d4-b89c-2c04cc01b71c.xR1YyxrEwTAUYzvxseaocd07_Us; request_token=KMakqkKidow7YyDmGylvP57BXkPCOAWIpoQnp302zq6RX6wD: network-unitType=KB/s; disk-unitType=MB/s; controlType=control
If-Modified-since: Wed, 22 Jul-2009 19:15:56 GMT
http响应消息格式
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 20 Feb 2017 09:13:59 GMT
Content-Type: text/plain;charset=UTF-8
Vary: Accept-Encoding
Cache-Control: no-store
Pragrma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache
Content-Encoding: gzip
Transfer-Encoding: chunked
Proxy-Connection: Keep-alive
{"code":200,"notice":0,"follow":0,"forward":0,"msg":0,"comment":0,"pushMsg":null,"friend":{"snsCount":0,"count":0,"celebrityCount":0},"lastPrivateMsg":null}
HTTP提供的方法
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
HTTP2.0协议是基于 HTTPS 的,速度是HTTP1.1的5倍以上,Tomcat8.5开始支持HTTP2.0。
1.头部压缩
HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,协议会帮你消除重复的部分。用 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,就提高速度了。
2. 二进制格式
HTTP/2全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)。计算机收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,增加了数据传输效率。
3.数据流
HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包。每个数据包都标记编号(Stream ID),可以并发不同的 Stream,接收端可以通过 Stream ID 有序组装成 HTTP 消息。
4.多路复用(连接共享)
HTTP/2 是可以在一个连接中并发多个请求或回应。不需要排队等待,也不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率。
5.服务器推送
HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务端不再是被动地响应,可以主动向客户端发送消息。
HTTP3.0基于 UDP 的 QUIC 协议 可实现类似 TCP 的可靠性传输。
1.无队头阻塞
在同一条连接上并发传输多个 Stream,Stream是一个 HTTP 请求。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。
2.更快的连接建立
在传输数据前虽然需要 QUIC 协议握手,只要 1 RTT,确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。
3.连接迁移
基于 TCP 传输协议的 HTTP 协议,通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。
QUIC 协议通过 连接ID来标记通信的两个端点,移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),可以“无缝”地复用原连接,消除重连的成本,达到了连接迁移的功能。