先认识一个协议叫做HTTP:
HTTP概念
HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
- 数据传输的规则指的是请求数据和响应数据需要按照指定的格式进行传输。
- 如果想知道具体的格式,可以打开浏览器,点击
F12打开开发者工具,点击Network来查看某一次请求的
HTTP协议特点
HTTP协议有它自己的一些特点,分别是:
- 基于TCP协议: 面向连接,安全
TCP是一种面向连接的(建立连接之前是需要经过三次握手)、可靠的、基于字节流的传输层通信协议,在数据传输方面更安全。 - 基于请求-响应模型的:一次请求对应一次响应
请求和响应是一一对应关系 - HTTP协议是无状态协议:对于事物处理没有记忆能力。每次请求-响应都是独立的
无状态指的是客户端发送HTTP请求给服务端之后,服务端根据请求响应数据,响应完后,不会记录任何信息。这种特性有优点也有缺点,- 缺点:多次请求间不能共享数据
- 优点:速度快
请求之间无法共享数据会引发的问题,如:
- 京东购物,
加入购物车和去购物车结算是两次请求, - HTTP协议的无状态特性,加入购物车请求响应结束后,并未记录加入购物车是何商品
- 发起去购物车结算的请求后,因为无法获取哪些商品加入了购物车,会导致此次请求无法正确展示数据
具体使用的时候,我们发现京东是可以正常展示数据的,原因是Java早已考虑到这个问题,并提出了使用会话技术(Cookie、Session)来解决这个问题。具体如何来做,我们后面会详细讲到。刚才提到HTTP协议是规定了请求和响应数据的格式,那具体的格式是什么呢?
请求数据格式:
请求数据总共分为三部分内容,分别是==请求行==、==请求头==、==请求体==
- 请求行: HTTP请求中的第一行数据,请求行包含三块内容,分别是 GET[请求方式] /[请求URL路径] HTTP/1.1[HTTP协议及版本]
请求方式有七种,最常用的是GET和POST 请求头: 第二行开始,格式为key: value形式
请求头中会包含若干个属性,常见的HTTP请求头有:Host: 表示请求的主机名User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ...Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...)like Gecko;Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。

这些数据有什么用处?
举例说明:服务端可以根据请求头中的内容来获取客户端的相关信息,有了这些信息服务端就可以处理不同的业务需求,比如:
- 不同浏览器解析HTML和CSS标签的结果会有不一致,所以就会导致相同的代码在不同的浏览器会出现不同的效果
- 服务端根据客户端请求头中的数据获取到客户端的浏览器类型,就可以根据不同的浏览器设置不同的代码来达到一致的效果
- 这就是我们常说的浏览器兼容问题
-
响应格式:
响应数据总共分为三部分内容,分别是==响应行==、==响应头==、==响应体==

响应行:响应数据的第一行,响应行包含三块内容,分别是 HTTP/1.1[HTTP协议及版本] 200[响应状态码] ok[状态码的描述]
- 响应头:第二行开始,格式为key:value形式
响应头中会包含若干个属性,常见的HTTP响应头有:
响应体: 最后一部分。存放响应数据Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;Content-Length:表示该响应内容的长度(字节数);Content-Encoding:表示该响应压缩算法,例如gzip;Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
上图中…这部分内容就是响应体,它和响应头之间有一个空行隔开。
2.3.2 响应状态码
参考: 资料/1.HTTP/《响应状态码.md》
关于响应状态码,我们先主要认识三个状态码,其余的等后期用到了再去掌握:
- 200 ok 客户端请求成功
- 404 Not Found 请求资源不存在
- 500 Internal Server Error 服务端发生不可预期的错误
认识这两个兄弟的作用:
就是一句话,request获取前端发过来的请求,response从后端设置响应给前端发送请求
Request继承体系
Request获取请求数据
Request请求转发
Request继承体系:

Request获取请求数据:
HTTP请求数据总共分为三部分内容,分别是==请求行、请求头、请求体==,对于这三部分内容的数据,分别该如何获取,首先我们先来学习请求行数据如何获取?
获取请求行数据:
请求行包含三块内容,分别是请求方式、请求资源路径、HTTP协议及版本
/*** request 获取请求数据*/@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// String getMethod():获取请求方式: GETString method = req.getMethod();System.out.println(method);//GET// String getContextPath():获取虚拟目录(项目访问路径):/request-demoString contextPath = req.getContextPath();System.out.println(contextPath);// StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1StringBuffer url = req.getRequestURL();System.out.println(url.toString());// String getRequestURI():获取URI(统一资源标识符): /request-demo/req1String uri = req.getRequestURI();System.out.println(uri);// String getQueryString():获取请求参数(GET方式): username=zhangsanString queryString = req.getQueryString();System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}}
获取请求头数据:
格式为key value形式:
/*** request 获取请求数据*/@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求头: user-agent: 浏览器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}}
获取请求体数据:
浏览器在发送GET请求的时候是没有请求体的,所以需要把请求方式变更为POST,请求体中的数据格式如下:

/*** request 获取请求数据*/@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);}}
BufferedReader流是通过request对象来获取的,当请求完成后request对象就会被销毁,request对象被销毁后,BufferedReader流就会自动关闭,所以此处就不需要手动关闭流了。
Response设置响应数据功能介绍
HTTP响应数据总共分为三部分内容,分别是==响应行、响应头、响应体==,对于这三部分内容的数据,respone对象都提供了哪些方法来进行设置?
响应行:
对于响应头比较常见的就是设置响应状态码:
void setStatus(int sc);
响应头:
设置响应头键值对:
void setHeader(String name,String value);
响应体:
对于响应体是通过字符 字节输出流的方式往浏览器上面写:
PrintWriter getWriter();
获取字节输出流:
ServletOutputStream getOutputStream();
@WebServlet("/resp1")public class ResponseDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("resp1....");//简化方式完成重定向//动态获取虚拟目录String contextPath = request.getContextPath();response.sendRedirect(contextPath+"/resp2");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}
/*** 响应字符数据:设置字符数据的响应体*/@WebServlet("/resp3")public class ResponseDemo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");//1. 获取字符输出流PrintWriter writer = response.getWriter();writer.write("aaa");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}
