【Java SE】HTTP与HTTPS通信协议

文章目录

  • 一、HTTP协议:互联网的基础通信协议
    • [1.1 什么是HTTP?](#1.1 什么是HTTP?)
    • [1.2 HTTP的发展历程](#1.2 HTTP的发展历程)
    • [1.3 HTTP的特性](#1.3 HTTP的特性)
  • 二、HTTP协议的核心组成
    • [2.1 HTTP报文格式](#2.1 HTTP报文格式)
      • [2.1.1 请求报文](#2.1.1 请求报文)
      • [2.1.2 响应报文](#2.1.2 响应报文)
    • [2.2 URL:资源的唯一标识](#2.2 URL:资源的唯一标识)
    • [2.3 HTTP请求方法](#2.3 HTTP请求方法)
    • [2.4 报头(Header)](#2.4 报头(Header))
    • [2.5 HTTP状态码](#2.5 HTTP状态码)
  • 三、HTTP的实际应用:如何构造HTTP请求?
    • [3.1 浏览器地址栏 + HTML标签](#3.1 浏览器地址栏 + HTML标签)
    • [3.2 HTML表单(form)](#3.2 HTML表单(form))
    • [3.3 AJAX](#3.3 AJAX)
      • [3.3.1 AJAX GET请求](#3.3.1 AJAX GET请求)
      • [3.3.2 AJAX POST请求(表单格式)](#3.3.2 AJAX POST请求(表单格式))
      • [3.3.3 AJAX POST请求(JSON格式)](#3.3.3 AJAX POST请求(JSON格式))
    • [3.4 后端代码构造(Java Socket示例)](#3.4 后端代码构造(Java Socket示例))
  • 四、HTTPS:HTTP的安全升级版
    • [4.1 为什么需要HTTPS?](#4.1 为什么需要HTTPS?)
    • [4.2 HTTPS的核心原理:加密机制](#4.2 HTTPS的核心原理:加密机制)
      • [4.2.1 对称加密](#4.2.1 对称加密)
      • [4.2.2 非对称加密](#4.2.2 非对称加密)
      • [4.2.3 证书与CA认证](#4.2.3 证书与CA认证)
    • [4.3 HTTPS的完整工作流程](#4.3 HTTPS的完整工作流程)
    • [4.4 HTTP与HTTPS的核心区别](#4.4 HTTP与HTTPS的核心区别)

一、HTTP协议:互联网的基础通信协议

1.1 什么是HTTP?

HTTP(HyperText Transfer Protocol,超文本传输协议)是一种应用层协议,诞生于1991年,如今已发展为互联网最主流的通信协议。它基于TCP/IP协议族工作,负责规范客户端(如浏览器)与服务器之间的数据传输格式和交互流程。

这里的"超文本"不仅指文本数据(如HTML、CSS),还包括图片、视频、音频等二进制资源。我们打开一个网站时,浏览器通过HTTP协议向服务器发送请求,服务器返回响应,响应内容经浏览器解析后,就变成了我们看到的网页界面。

1.2 HTTP的发展历程

HTTP协议历经多次迭代,不断优化性能和功能:

  • HTTP/0.9(1991):最初版本,仅支持GET方法,只能传输纯文本HTML。
  • HTTP/1.0(1997):新增POST、HEAD等方法,支持多种数据类型(图片、音频等),引入HTTP头部字段。
  • HTTP/1.1(1999):目前应用最广泛的版本,支持长连接(Keep-Alive)、管道化请求、Chunked编码等,解决了1.0版本的性能瓶颈。
  • HTTP/2.0:基于二进制帧传输,支持多路复用、头部压缩、服务器推送,大幅提升传输效率。
  • HTTP/3.0:正在完善中,基于UDP协议实现,解决了TCP协议的队头阻塞问题,Google、Facebook等大厂已率先支持。

1.3 HTTP的特性

  • 无状态:协议本身不记录客户端的历史交互信息,每次请求都是独立的。如需保持状态(如登录状态),需通过Cookie、Session等机制实现。
  • 基于请求-响应模式:客户端主动发送请求,服务器被动返回响应,不存在服务器主动向客户端推送数据的情况(HTTP/2.0的服务器推送除外)。
  • 文本协议:HTTP报文是明文的文本格式,便于调试和理解,但也存在安全隐患。

二、HTTP协议的核心组成

2.1 HTTP报文格式

HTTP通信的基本单位是报文,分为请求报文和响应报文,两者结构相似,均由 "首行+头部+空行+正文" 四部分组成。

2.1.1 请求报文

以访问CSDN页面为例:

  • 首行:格式为方法 + URL + 协议版本
  • 请求头(Header):由多个键值对组成,每个键值对占一行,键和值用: (空格)分隔,头部用于描述请求的属性,如数据类型、缓存策略等。http请求头中键的取值和值的取值都是固定的
  • 空行:用于分隔头部和正文,是HTTP协议的强制要求,避免出现"粘包问题"。
  • 正文(Body):可选部分,用于传输请求数据(如POST请求的表单数据),长度由Content-Length头部字段指定。

2.1.2 响应报文

  • 首行:格式为协议版本 + 状态码 + 状态码描述
  • 响应头(Header):与请求头部格式一致,包含响应的属性
  • 空行:分隔头部和正文。
  • 正文(Body):服务器返回的实际数据,可以是HTML页面、JSON数据、图片等。

2.2 URL:资源的唯一标识

我们俗称的"网址"其实是URL(Uniform Resource Locator,统一资源定位符),它唯一标识互联网上的一个资源。URL的完整格式如下:

复制代码
http://www.example.com:80/dir/index.htm?uid=1#ch1

各部分含义:

  • 协议方案名:如http、https,也可以是jdbc:mysql(访问MySQL数据库)等。
  • 服务器地址(www.example.com):可以是域名IP地址,域名会通过DNS解析为IP。
  • 服务器端口号(:80):HTTP默认端口80,HTTPS默认443,省略时使用默认端口。
  • 带层次的文件路径(/dir/index.htm):想要访问的是某个主机(IP确定)上某个程序(端口号确定)管理的某个资源在服务器上的存储路径。层次可以理解为目录。
  • 查询字符串[Querry String](?uid=1):键值对结构,用于向服务器传递额外参数,键值对之间用&分隔,键与值用= 分割。
  • 片段标识(#ch1):用于页面内跳转,不会发送到服务器。常用于文档类网站。

2.3 HTTP请求方法

HTTP定义了多种请求方法,用于表示对资源的操作意图,常用方法如下:

方法 说明 特点
GET 获取资源 无请求正文,参数通过URL传递,可缓存,幂等
POST 提交数据 有请求正文,参数通过正文传递,不可缓存,非幂等
PUT 更新资源 用于全量更新资源,幂等
DELETE 删除资源 用于删除服务器资源,幂等
HEAD 获取响应头部 与GET类似,但仅返回响应头部,无正文
OPTIONS 询问支持的方法 用于获取服务器支持的HTTP方法

GET与POST的区别

GET和POST没有本质区别,大多数情况都可以混用

  • 语义不同:GET用于"获取"资源,POST用于"提交"数据。
  • 数据传输方式:GET一般没有body,通过Query String传递数据,POST通过正文传递。
  • 缓存特性:GET请求可被浏览器缓存,POST请求不可缓存。
  • 幂等性:GET请求建议设计为多次执行结果一致(幂等),POST请求多次执行可能产生不同结果(如重复提交订单)。
  • POST典型使用场景:登录、上传。请求中带有正文的,正文就是保存了当前上传的数据内容

2.4 报头(Header)

报头中常见的键值对:

  • Host:表示服务器主机的地址和端口号。绝大情况下Host与URL中的IP地址和端口号属性是一致的。在HTTPS协议中,传输过程涉及到加密,url部分不会被加密,而header和body部分会被加密

  • Content-Length:表示body中数据长度,单位是字节。对于TCP来说,一个链接可以发送多个请求,而服务器收到的数据需要区分:

    • 没有body的http请求:读到空行就可以认为是结束了
    • 有body的http请求:先读取首行和header,读到空行;解析header中Content-Length的值,再读固定的字节长度
  • Content-Type:表示body中数据格式。

类型 取值 浏览器解析方式
HTML text/html 解析其中的标签,把标签转换为界面显示
CSS text/css 解析其中的选择器和属性,把指定内容应用到页面样式上
JS application/javascript 通过JS引擎执行JS中的逻辑
JSON application/json 浏览器不会做任何处理,由对应的JS,也就是程序员写的逻辑来处理
图片 image/png(jpg) 按照图片的二进制格式解析出来处理

2.5 HTTP状态码

状态码用于表示服务器对请求的处理结果,分为5大类:

类别 含义 常见状态码
1XX 信息性状态码 100 Continue(继续)
2XX 成功状态码 200 OK(请求成功)、204 No Content(无内容)
3XX 重定向状态码 301 永久重定向、302 临时重定向、304 Not Modified(缓存命中)
4XX 客户端错误状态码 400 Bad Request(请求参数错误)、403 Forbidden(访问拒绝)、404 Not Found(资源不存在)
5XX 服务器错误状态码 500 Internal Server Error(服务器内部错误)、504 Gateway Timeout(网关超时)

常见状态码场景:

  • 200 OK:最常见,表明请求成功,服务器返回了请求的资源。
  • 404 Not Found:URL对应的资源不存在,可能是地址输入错误。
  • 403 Forbidden:服务器拒绝访问,通常是未登录或无权限。
  • 418 I am a teapot:我是一个茶壶🤪 彩蛋
  • 500 Internal Server Error:服务器代码执行出错(如程序bug)。
  • 302 临时重定向:常用于登录成功后跳转到主页。

三、HTTP的实际应用:如何构造HTTP请求?

在实际开发中,我们可以通过多种方式构造HTTP请求,以下是常见场景:

3.1 浏览器地址栏 + HTML标签

  • 浏览器地址栏输入URL:直接发送GET请求。
  • HTML标签:<link>(加载CSS)、<img>(加载图片)、<script>(加载JS)等标签会自动发送GET请求。

3.2 HTML表单(form)

form标签是HTML中用于提交数据的核心标签,支持GET和POST方法:

  • GET 请求
html 复制代码
<form action="https://www.example.com/api" method="GET">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="password" placeholder="密码">
  <input type="submit" value="登录">
</form>
  • POST 请求
html 复制代码
<form action="https://www.example.com/api" method="POST">
  <input type="text" name="username" placeholder="用户名">
  <input type="password" name="password" placeholder="密码">
  <input type="submit" value="登录">
</form>
  • action:指定请求的URL。
  • method:指定请求方法(GET/POST)。
  • input标签的name属性:作为请求参数的key,value为用户输入的内容。

3.3 AJAX

AJAX(Asynchronous JavaScript and XML)是一种异步发送HTTP请求的技术,无需刷新页面即可与服务器交互。以下是使用jQuery实现的AJAX请求示例:

3.3.1 AJAX GET请求

javascript 复制代码
$.ajax({
  type: 'GET',
  url: 'https://www.example.com/api?username=zhangsan',
  success: function(data) {
    console.log('响应数据:', data);
  }
});

3.3.2 AJAX POST请求(表单格式)

javascript 复制代码
$.ajax({
  type: 'POST',
  url: 'https://www.example.com/api',
  contentType: 'application/x-www-form-urlencoded',
  data: 'username=zhangsan&password=123456',
  success: function(data) {
    console.log('响应数据:', data);
  }
});

3.3.3 AJAX POST请求(JSON格式)

javascript 复制代码
$.ajax({
  type: 'POST',
  url: 'https://www.example.com/api',
  contentType: 'application/json',
  data: JSON.stringify({ username: 'zhangsan', password: '123456' }),
  success: function(data) {
    console.log('响应数据:', data);
  }
});

3.4 后端代码构造(Java Socket示例)

HTTP请求本质是按照协议格式构造的字符串,通过TCP Socket发送给服务器。以下是Java实现的简单HTTP客户端:

java 复制代码
public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;

    public HttpClient(String ip, int port) throws IOException {
        this.ip = ip;
        this.port = port;
        socket = new Socket(ip, port);
    }

    // GET请求
    public String get(String url) throws IOException {
        StringBuilder request = new StringBuilder();
        // 首行
        request.append("GET " + url + " HTTP/1.1\n");
        // 头部
        request.append("Host: " + ip + ":" + port + "\n");
        // 空行(分隔头部和正文)
        request.append("\n");
        // 发送请求
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
    }

    // POST请求
    public String post(String url, String body) throws IOException {
        StringBuilder request = new StringBuilder();
        // 首行
        request.append("POST " + url + " HTTP/1.1\n");
        // 头部
        request.append("Host: " + ip + ":" + port + "\n");
        request.append("Content-Length: " + body.getBytes().length + "\n");
        request.append("Content-Type: text/plain\n");
        // 空行
        request.append("\n");
        // 正文
        request.append(body);
        // 发送请求
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
    }

    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient("www.sogou.com", 80);
        // 发送GET请求
        String getResp = client.get("/");
        System.out.println("GET响应:" + getResp);
        // 发送POST请求
        String postResp = client.post("/api", "username=zhangsan");
        System.out.println("POST响应:" + postResp);
    }
}

四、HTTPS:HTTP的安全升级版

4.1 为什么需要HTTPS?

HTTP协议的最大问题是明文传输,数据在传输过程中可能被篡改、窃取或劫持(如运营商劫持、黑客攻击)。

HTTPS(HTTP Secure)正是为解决HTTP的安全问题而生,它在HTTP基础上增加了SSL/TLS加密层,实现数据传输的机密性、完整性和身份认证。

4.2 HTTPS的核心原理:加密机制

HTTPS结合了对称加密非对称加密的优点,既保证安全性,又兼顾传输效率。

4.2.1 对称加密

  • 特点:使用同一个密钥进行加密和解密,运算速度快,但密钥传输存在安全风险(密钥被窃取则加密失效)。
  • 示例:按位异或运算,明文a=1234与密钥key=8888异或得到密文9834,密文再与密钥异或可还原明文。

4.2.2 非对称加密

  • 特点:使用一对密钥(公钥+私钥),公钥可公开,私钥仅持有者拥有。公钥加密的密文只能用私钥解密,私钥加密的密文只能用公钥解密。运算速度慢,但密钥传输安全。
  • 应用场景:用于协商对称加密的密钥,避免密钥明文传输。

4.2.3 证书与CA认证

为解决"公钥伪造"问题(中间人替换服务器公钥),HTTPS引入了数字证书CA(Certificate Authority)认证

  • 服务器向CA机构申请数字证书,证书包含服务器公钥、域名、有效期等信息,并由CA机构用私钥签名。
  • 客户端获取证书后,通过操作系统内置的CA公钥验证签名,确认证书合法性(未篡改、未过期)。
  • 只有验证通过的证书,客户端才会使用证书中的公钥进行后续通信。

4.3 HTTPS的完整工作流程

  1. 客户端向服务器发送HTTPS请求,请求中包含支持的加密算法和哈希算法。
  2. 服务器返回数字证书(包含公钥)和选定的加密/哈希算法。
  3. 客户端验证证书合法性:
    • 检查证书有效期是否过期。
    • 检查证书发布机构是否受信任(操作系统内置信任的CA)。
    • 用CA公钥解密证书签名,与本地计算的证书哈希值对比,确认证书未被篡改。
  4. 证书验证通过后,客户端生成随机对称密钥R,用服务器公钥加密R,发送给服务器。
  5. 服务器用私钥解密,获取对称密钥R。
  6. 后续通信:客户端和服务器均使用对称密钥R加密/解密数据,实现安全传输。

4.4 HTTP与HTTPS的核心区别

特性 HTTP HTTPS
传输方式 明文传输 SSL/TLS加密传输
端口 80 443
安全性 无身份认证、数据易被篡改/窃取 有身份认证、数据机密性和完整性保障
性能 无加密开销,性能略高 加密/解密有开销,性能略低
证书 无需证书 需向CA申请数字证书
相关推荐
靠沿4 小时前
Java数据结构初阶——LinkedList
java·开发语言·数据结构
qq_12498707534 小时前
基于springboot的建筑业数据管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
一 乐4 小时前
宠物管理|宠物共享|基于Java+vue的宠物共享管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·springboot·宠物
a crazy day4 小时前
Spring相关知识点【详细版】
java·spring·rpc
白露与泡影5 小时前
MySQL中的12个良好SQL编写习惯
java·数据库·面试
foundbug9995 小时前
配置Spring框架以连接SQL Server数据库
java·数据库·spring
凯酱5 小时前
@JsonSerialize
java
cccyi75 小时前
HTTP 协议详解:从基础到核心特性
网络协议·http·应用层
悦悦子a啊5 小时前
项目案例作业(选做):使用文件改造已有信息系统
java·开发语言·算法
lkbhua莱克瓦245 小时前
Java项目——斗地主小游戏(控制台版)
java·开发语言·windows·斗地主项目