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
英文地址,請注明出處:http://en.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;收藏?評論? 今天水一篇吧…