8.4 Java 原生 TCP Socket 实现 HTTP 请求解析和请求分发

使用 Java 原生 TCP Socket 实现 HTTP 请求解析和请求分发,是一个理解 HTTP 协议底层原理的好方法。虽然 Java 提供了 HttpServer 类来简化 HTTP 服务器开发,但如果你想从 TCP 层 开始构建一个简单的 HTTP 服务器,可以使用 ServerSocketSocket 实现。

在进行web开发前.我们扩展一下 8.3 Java HTTP-CSDN博客 的内容.实现http请求分发


使用 Java 原生 TCP Socket 实现:

  1. 接收 HTTP 请求(GET/POST)
  2. 解析请求头和请求路径
  3. 根据路径分发请求到不同处理方法
  4. 返回 HTTP 响应

实现代码

1. 引入基础类

import java.io.*;
import java.net.*;
import java.util.*;

2. 定义处理接口

@FunctionalInterface
interface HttpRequestHandler {void handle(HttpRequest request, HttpResponse response) throws IOException;
}

3. 定义请求和响应封装类

class HttpRequest {String method;String path;Map<String, String> headers = new HashMap<>();String body;public HttpRequest(String method, String path, Map<String, String> headers, String body) {this.method = method;this.path = path;this.headers = headers;this.body = body;}
}
 
class HttpResponse {private BufferedWriter out;private OutputStream rawOut;public HttpResponse(BufferedWriter out, OutputStream rawOut) {this.out = out;this.rawOut = rawOut;}public void send(int statusCode, String contentType, String responseBody) throws IOException {String statusLine = statusCode == 200 ? "HTTP/1.1 200 OK" : "HTTP/1.1 404 Not Found";String response =statusLine + "\r\n" +"Content-Type: " + contentType + "\r\n" +"Content-Length: " + responseBody.length() + "\r\n" +"Connection: close\r\n" +"\r\n" +responseBody;out.write(response);out.flush();}public void sendFile(int statusCode, String contentType, byte[] fileBytes) throws IOException {String statusLine = statusCode == 200 ? "HTTP/1.1 200 OK" : "HTTP/1.1 404 Not Found";String header =statusLine + "\r\n" +"Content-Type: " + contentType + "\r\n" +"Content-Length: " + fileBytes.length + "\r\n" +"Connection: close\r\n" +"\r\n";rawOut.write(header.getBytes());rawOut.write(fileBytes);rawOut.flush();}
}

4. 定义主服务器类

public class SimpleHttpServerUsingTCP {private static final int PORT = 8080;private static Map<String, HttpRequestHandler> routeMap = new HashMap<>();public static void main(String[] args) throws IOException {routeMap.put("/hello", (req, res) -> {try {res.send(200, "text/plain", "Hello, World!");} catch (IOException e) {e.printStackTrace();}});routeMap.put("/about", (req, res) -> {try {res.send(200, "text/plain", "This is a simple HTTP server using TCP.");} catch (IOException e) {e.printStackTrace();}});ServerSocket serverSocket = new ServerSocket(PORT);System.out.println("Server started on port " + PORT);while (true) {Socket clientSocket = serverSocket.accept();handleClient(clientSocket);}}private static void handleClient(Socket socket) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));OutputStream rawOut = socket.getOutputStream();String line = in.readLine();if (line == null || line.isEmpty()) return;System.out.println("Request: " + line);// 解析请求行String[] requestLine = line.split(" ");String method = requestLine[0];String path = requestLine[1];// 解析请求头Map<String, String> headers = new HashMap<>();while (!(line = in.readLine()).isEmpty()) {String[] header = line.split(": ");if (header.length == 2) {headers.put(header[0], header[1]);}}// 读取请求体(仅处理 POST)int contentLength = 0;if (headers.containsKey("Content-Length")) {contentLength = Integer.parseInt(headers.get("Content-Length"));}char[] bodyBuffer = new char[contentLength];in.read(bodyBuffer, 0, contentLength);String body = new String(bodyBuffer);// 构建请求和响应对象HttpRequest request = new HttpRequest(method, path, headers, body);HttpResponse response = new HttpResponse(out, rawOut);// 路由分发HttpRequestHandler handler = routeMap.get(path);if (handler != null) {handler.handle(request, response);} else {response.send(404, "text/plain", "404 Not Found");}socket.close();}
}

测试方式

使用浏览器访问:

http://localhost:8080/hello
http://localhost:8080/about
http://localhost:8080/unknown

使用 curl 测试:

curl http://localhost:8080/hello
# 输出: Hello, World!curl http://localhost:8080/about
# 输出: This is a simple HTTP server using TCP.curl http://localhost:8080/unknown
# 输出: 404 Not Found

 支持 POST 请求(可选扩展)

你可以通过解析请求体,支持 POST 请求,例如:

routeMap.put("/post", (req, res) -> {System.out.println("Received POST body: " + req.body);res.send(200, "text/plain", "POST received: " + req.body);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92271.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自研能管项目开发界面

自研能管软件实现一个界面开发 目的&#xff1a; ​ 通过接口方式实现展示哪些数据例如&#xff1a; ​ 已知制丝车间下的计量电表&#xff0c;在可视化界面通过点击制丝车间的方式&#xff0c;自动在MySQL存储制丝车间的电表数据(假设是每分钟存储一次)&#xff0c;前端即可以…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 基于wordcloud库实现词云图

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解基于wordcloud库实现词云图 视频在线地址&…

Vue3 面试题及详细答案120道(31-45 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

Proxmox VE 8.3/8.4开启Intel 核显的vGPU,搭建vGPU云桌面系统

1. Intel Graphics SR-IOV 介绍Intel Graphics SR-IOV 是 Intel 最新的图形虚拟化技术。单根 I/O 虚拟化 &#xff08;SR-IOV&#xff09; 通过将设备划分为多个虚拟功能来定义共享物理设备功能的标准方法。每个虚拟函数都直接分配给一个虚拟机&#xff0c;从而为虚拟机实现接近…

LeetCode 热题100

文章目录哈希两数之和字母异位词分组最长连续序列双指针移动零盛最多水的容器滑动窗口子串多刷题 LeetCode 热题100 哈希 两数之和 思路分析&#xff1a; 暴力做法&#xff1a;每一个数字都与剩余的数字作比较&#xff0c;时间复杂度是O(n2)O(n^2)O(n2)哈希做法&#xff1a;我…

Idea或Pycharm上.idea的忽略提交的问题总结

文章目录问题描述如果是首次提交或者之后的提交代码时把.idea及其文件提交到远端仓库中&#xff0c;此时再创建.gitignore会不生效。问题描述 由于在代码托管平台上创建的项目&#xff0c;没有关联创建.gitignore文件。导致git 克隆到本地电脑上时&#xff0c;项目的根目录下也…

【锁】MySQL中有哪几种锁?

&#x1f4da; 欢迎来到我的Java八股文专栏&#xff01; &#x1f389; 各位程序员小伙伴们好呀~ &#x1f44b; 我是雪碧聊技术&#xff0c;很高兴能在CSDN与大家相遇&#xff01;✨ &#x1f680; 专栏介绍 这个专栏将专注于分享Java面试中的经典"八股文"知识点 &a…

旷视科技视觉算法面试30问全景精解

旷视科技视觉算法面试30问全景精解 ——AI赋能 智能安防 视觉创新&#xff1a;旷视科技视觉算法面试核心考点全览 前言 旷视科技&#xff08;Megvii&#xff09;作为全球领先的人工智能公司&#xff0c;专注于计算机视觉、深度学习和智能安防等领域&#xff0c;推动人脸识别、…

docker nginx 部署前端踩坑记录

文章目录坑点1&#xff1a;localhost 与127.0.0.1坑点1&#xff1a;localhost 与127.0.0.1 server {listen 80 default_server;client_max_body_size 20M;# 记录访问日志和错误日志access_log /var/log/nginx/host.access.log main;error_log /var/log/nginx/error.l…

JAVA_TEN-面向对象高级一

一.Static一 定义&#xff1a;叫静态&#xff0c;可以修饰成员变量、成员方法成员变量按有无static修饰&#xff0c;分为两种&#xff1a;类变量&#xff1a;有static 修饰&#xff0c;属于类&#xff0c;在计算机里只有一份&#xff0c;会被类的全部对象共享。实例变量&#x…

幻兽帕鲁开服教程

以下均为个人推荐&#xff0c;不喜勿喷&#xff0c;望审核大大明辨开服条件一台带公网的vps服务器&#xff08;需开放udp&#xff09;&#xff0c;配置至少为4c16g&#xff0c;推荐8c32g开服需要准备的工具&#xff1a;steamcmd&#xff1a;https://steamcdn-a.akamaihd.net/cl…

lesson21:Python面向对象编程

目录 引言 一、了解面向对象编程&#xff08;OOP&#xff09;&#xff1a;编程范式的革命 1.1 什么是面向对象编程&#xff1f; 1.2 OOP vs 面向过程&#xff1a;思维方式的差异 1.3 OOP的三大核心特性 二、类与对象&#xff1a;OOP的基石 2.1 类&#xff08;Class&#…

基于卷积神经网络与小波变换的医学图像超分辨率算法复现

基于卷积神经网络与小波变换的医学图像超分辨率算法复现 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 1. 引言 医学图像超分辨率技术在临床诊断和治疗规划…

HCIP第一二章笔记整理

第一章&#xff1a;复习HCIA第一阶段应用层&#xff1a;自然语言转换为编码表示层&#xff1a;编码转换为二进制介质访问控制层&#xff1a;二进制转化为信号物理层&#xff1a;传输电信号第二阶段&#xff1a;OSI参考模型应用层&#xff1a;提供网络服务表示层&#xff1a;对数…

《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——2. C++基础:构建程序的坚实骨架

目录一、概述1.1 背景介绍&#xff1a;从UI到逻辑1.2 学习模式&#xff1a;Qt控制台应用二、C语法快速入门2.1 变量、数据类型与注释2.2 函数与代码封装2.3 循环与容器&#xff1a;批量处理三、面向对象编程&#xff1a;封装数据与行为四、Qt的核心扩展&#xff1a;信号与槽通信…

Navicat 远程连接SQLlite数据库

1、SQLlite数据库是一个本地.db文件&#xff0c;默认不支持远程连接&#xff1b; 2、Navicat 可以通过ntunnel_sqlite.php文件连接远程SQLlite库&#xff1b; 3、安装Navicat&#xff0c;安装完成&#xff0c;在安装目录下找到ntunnel_sqlite.php文件&#xff1b; 4、上传当前文…

OpenCV用于计算光流的一个类cv::optflow::DualTVL1OpticalFlow

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::optflow::DualTVL1OpticalFlow 是 OpenCV 中用于计算光流的一个类&#xff0c;特别地&#xff0c;它实现了基于双帧 TV-L1&#xff08;Total V…

PyQt5在Pycharm上的环境搭建 -- Qt Designer + Pyuic + Pyrcc组合,大幅提升GUI开发效率

软件安装 目标软件&#xff1a; Python解释器Pycharm编辑器 Python官网&#xff1a; 点击访问Python官网 Pycharm官网&#xff1a;点击访问Pycharm官网 环境搭建 搭建完成后最终的环境详情&#xff1a; python安装路径&#xff1a;D:\ProgramEnviron\Python\Python311Pyth…

30天打牢数模基础-卷积神经网络讲解

案例代码实现一、代码说明本案例使用PyTorch实现一个改进版LeNet-5模型&#xff0c;用于CIFAR-10数据集的图像分类任务。代码包含以下核心步骤&#xff1a;数据加载与预处理&#xff08;含数据增强&#xff0c;划分训练/验证/测试集&#xff09;&#xff1b;定义CNN网络结构&am…

Dev-C++——winAPI贪吃蛇小游戏

&#x1f680;欢迎互三&#x1f449;&#xff1a;雾狩 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 今天水一篇吧…