当前位置: 首页 > news >正文

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.dtcms.com/a/292337.html

相关文章:

  • OpenCV基本的图像处理
  • 本地数据库有数据,web页面无信息显示,可能是pymysql的版本问题【pymysql连接本地数据库新旧版本的区别】
  • 【测试开发】----用例篇
  • 高并发场景下的缓存问题与一致性解决方案(技术方案总结)
  • 设计模式——责任链模式
  • 建造者设计模式
  • Qt布局管理:实现美观界面的关键
  • 2025 年最新 AI 技术:全景洞察与深度解析​
  • 从 0 到 1 搞定nvidia 独显推流:硬件视频编码环境安装完整学习笔记
  • Arraylist与LinkedList区别
  • 使用react编写一个简单的井字棋游戏
  • ZLMediaKit 入门
  • 第12天 | openGauss逻辑结构:模式管理
  • Java 大视界 -- Java 大数据在智能医疗医疗设备维护与管理中的应用(358)
  • 25. K 个一组翻转链表
  • Odoo:免费开源的金属制品行业ERP管理软件
  • React 面试题库
  • 写个 flask todo app,简洁,实用
  • calibrate_hand_eye (CalibDataID, Errors)
  • 2025年远程桌面软件深度评测:ToDesk、向日葵、TeamViewer全方位对比分析
  • C++学习——内联、C++11中的auto、for循环、nullptr
  • Windows Cmake Vs2017/2010 编译安装Protobuf
  • 【计算机网络】第五章:传输层
  • 双向链表详解及实现
  • 解锁高品质音频体验:探索音频质量评估与测试的科学之道
  • Vibe Coding:人工智能 + 语音 = 新型开发者工作流
  • Thingsboard是什么?跟LoRaWAN 是什么关系?
  • 图像基础:从像素到 OpenCV 的入门指南
  • 【加解密与C】Rot系列(四)RotSpecial
  • 【windows修复】解决windows10,没有【相机] 功能问题