HTTP-响应协议(响应状态码、HTTP-协议解析)

HTTP-响应协议

2.3.1 格式介绍

与HTTP的请求一样,HTTP响应的数据也分为3部分:响应行响应头响应体

  • 响应行(以上图中红色部分):响应数据的第一行。响应行由协议及版本响应状态码状态码描述组成

    • 协议/版本:HTTP/1.1
    • 响应状态码:200
    • 状态码描述:OK
  • 响应头(以上图中黄色部分):响应数据的第二行开始。格式为key:value形式

    • http是个无状态的协议,所以可以在请求头和响应头中设置一些信息和想要执行的动作,这样,对方在收到信息后,就可以知道你是谁,你想干什么

    常见的HTTP响应头有:

    复制代码
    Content-Type:表示该响应内容的类型,例如text/html,image/jpeg ;
    
    Content-Length:表示该响应内容的长度(字节数);
    
    Content-Encoding:表示该响应压缩算法,例如gzip ;
    
    Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒 ;
    
    Set-Cookie: 告诉浏览器为当前页面所在的域设置cookie ;
  • 响应体(以上图中绿色部分): 响应数据的最后一部分。存储响应的数据
    • 响应体和响应头之间有一个空行隔开(作用:用于标记响应头结束)
2.3.2 响应状态码
状态码分类 说明
1xx 响应中 --- 临时状态码。表示请求已经接受,告诉客户端应该继续请求或者如果已经完成则忽略
2xx 成功 --- 表示请求已经被成功接收,处理已完成
3xx 重定向 --- 重定向到其它地方,让客户端再发起一个请求以完成整个处理
4xx 客户端错误 --- 处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx 服务器端错误 --- 处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

参考: 资料/SpringbootWeb/响应状态码.md

关于响应状态码,我们先主要认识三个状态码,其余的等后期用到了再去掌握:

  • 200 ok 客户端请求成功
  • 404 Not Found 请求资源不存在
  • 500 Internal Server Error 服务端发生不可预期的错误

2.4 HTTP-协议解析

将资料中准备好的Demo工程,导入到我们的IDEA中,有一个Server.java类,这里面就是自定义的一个服务器代码,主要使用到的是ServerSocketSocket

说明:以下代码大家不需要自己写,我们主要是通过代码,让大家了解到服务器针对HTTP协议的解析机制

java 复制代码
package com.itheima;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/*
 * 自定义web服务器
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 监听指定端口
        System.out.println("server is running...");

        while (true){
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}

class Handler extends Thread {
    Socket sock;

    public Handler(Socket sock) {
        this.sock = sock;
    }

    public void run() {
        try (InputStream input = this.sock.getInputStream();
             OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
        } catch (Exception e) {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // 读取HTTP请求:
        boolean requestOk = false;
        String first = reader.readLine();
        if (first.startsWith("GET / HTTP/1.")) {
            requestOk = true;
        }
        for (;;) {
            String header = reader.readLine();
            if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
                break;
            }
            System.out.println(header);
        }
        System.out.println(requestOk ? "Response OK" : "Response Error");

        if (!requestOk) {// 发送错误响应:
            writer.write("HTTP/1.0 404 Not Found\r\n");
            writer.write("Content-Length: 0\r\n");
            writer.write("\r\n");
            writer.flush();
        } else {// 发送成功响应:
            //读取html文件,转换为字符串
            InputStream is = Server.class.getClassLoader().getResourceAsStream("html/a.html");
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder data = new StringBuilder();
            String line = null;
            while ((line = br.readLine()) != null){
                data.append(line);
            }
            br.close();
            int length = data.toString().getBytes(StandardCharsets.UTF_8).length;

            writer.write("HTTP/1.1 200 OK\r\n");
            writer.write("Connection: keep-alive\r\n");
            writer.write("Content-Type: text/html\r\n");
            writer.write("Content-Length: " + length + "\r\n");
            writer.write("\r\n"); // 空行标识Header和Body的分隔
            writer.write(data.toString());
            writer.flush();
        }
    }
}

启动ServerSocket程序:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<table border="1" cellspacing="0" width="500">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>

    </tr>
    <tr align="center">
        <td>010</td>
        <td>三只松鼠</td>
        <td>三只松鼠</td>
    </tr>

    <tr align="center">
        <td>009</td>
        <td>优衣库</td>
        <td>优衣库</td>
    </tr>

    <tr align="center">
        <td>008</td>
        <td>小米</td>
        <td>小米科技有限公司</td>
    </tr>


</table>


</body>
</html>

浏览器输入:http://localhost:8080 就会访问到ServerSocket程序

  • ServerSocket程序,会读取服务器上html/a.html文件,并把文件数据发送给浏览器
  • 浏览器接收到a.html文件中的数据后进行解析,显示以下内容

现在大家知道了服务器是可以使用java完成编写,是可以接受页面发送的请求和响应数据给前端浏览器的,而在开发中真正用到的Web服务器,我们不会自己写的,都是使用目前比较流行的web服务器。如:Tomcat

相关推荐
REDcker7 小时前
埋点系统设计:从成熟工具到自建方案
运维·服务器·网络·用户分析·埋点·埋点系统
任白7 小时前
OSI参考模型&&TCP/IP模型
网络协议
不做菜鸟的网工7 小时前
OSPF协议笔记整理
网络协议
优橙教育7 小时前
通信行业四大热门岗位解析:谁才是数字时代的黄金赛道?
网络·学习·5g
迎仔8 小时前
11-云网络与混合云运维:弹性数字世界的交通管理
网络·安全·web安全
Trouvaille ~8 小时前
【Linux】应用层协议设计实战(二):Jsoncpp序列化与完整实现
linux·运维·服务器·网络·c++·json·应用层
pitch_dark8 小时前
渗透测试系统基础篇——kali系统
网络·安全·web安全
独行soc8 小时前
2026年渗透测试面试题总结-20(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
EmbedLinX8 小时前
嵌入式之协议解析
linux·网络·c++·笔记·学习
凉、介8 小时前
VMware 三种网络模式(桥接 / NAT / Host-Only)原理与实验解析
c语言·网络·笔记·操作系统·嵌入式·vmware