Java 18 中的簡單 Web 伺服器
1. 概述
從 Java 18 開始,我們可以存取JEP 408中引入的簡單 Web 伺服器。我們可以透過命令列工具和 API 存取其功能。
簡單 Web 伺服器提供了一個提供靜態檔案服務的基本 Web 伺服器。它被描述為對於測試、原型設計和教育很有用。該伺服器有意使其設定和運行非常簡單,並非旨在與 Apache Tomcat 或 Jetty 等功能更齊全的選項競爭或取代。
引入該工具的目標之一是讓開發人員以盡可能少的障礙啟動並執行 Web 開發。
在本教程中,我們將了解簡單 Web 伺服器及其工作原理。
jwebserver
命令列工具
啟動伺服器的第一個也是最簡單的方法是使用提供的命令列工具。
2.1.啟動
我們這裡需要的指令是jwebserver
。單獨使用指令jwebserver
就足以啟動伺服器。
如果一切正常,我們會看到以下回應:
$ jwebserver
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /usr and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/
預設情況下,執行指令時所在的目錄就是所提供的目錄,即上例中的/usr
。但是,我們可以使用-d
標誌更改目錄:
$ jwebserver -d /opt
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /opt and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/
值得注意的是,我們必須在這裡提供絕對路徑。
我們也可以使用-p
和-b
標誌來更改連接埠和位址:
$ jwebserver -b 0.0.0.0 -p 3003
Serving / and subdirectories on 0.0.0.0 (all interfaces) port 3003
URL http://192.168.1.1:3003/
執行上述配置會將我們的目前目錄公開給網路上輸出中給出的 IP 位址的任何人。雖然如果我們嘗試傳輸文件,這可能很有用,但我們應該確保我們樂意首先共享它們。
2.2.獲取請求
我們可以使用瀏覽器存取 Web 伺服器,導航到正確的位址和連接埠。到達那裡後,我們將在啟動伺服器的目錄中看到檔案和子目錄的清單:
如果我們隨後訪問這些文件中的任何一個,我們將在瀏覽器中看到它們,並在終端機中看到一個新行:
127.0.0.1 - - [09/Feb/2024:12:06:26 +0000] "GET /file.txt HTTP/1.1" 200 -
同樣,當進入新的子目錄時,我們將看到我們正在存取的目錄記錄的 GET 請求:
127.0.0.1 - - [09/Feb/2024:12:06:52 +0000] "GET /subdirectory/ HTTP/1.1" 200 -
3、接口
使用簡單 Web 伺服器的第二個選項是 API。透過使用它,我們可以獲得更多的控制權並自訂請求的處理方式。
3.1.定義伺服器
首先,讓我們使用 API 重新建立命令列 Web 伺服器。
為此,我們將使用**SimpleFileServer.**
我們可以使用這個類別來做三件事——創建HttpServer
、創建HttpHandler,
和創建HttpFilter
。
首先,我們將使用createFileServer()
建立並啟動伺服器:
public static void main(String[] args) {
InetSocketAddress address = new InetSocketAddress(8080);
Path path = Path.of("/");
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.start();
}
這裡我們使用InetSocketAddress
類別指定了一個位址。我們還可以更改此處地址的其餘部分,而不僅僅是連接埠。
然後,我們設定了一個指向我們想要服務的目錄的Path
物件。
接下來,我們將這些作為參數以及日誌記錄等級傳遞給createFileServer()
。和以前一樣,我們可以配置其中任何一個來滿足我們的需求。產生的 Web 伺服器與使用命令列工具建立的 Web 伺服器相同,可以透過我們的瀏覽器存取127.0.0.1:8080
。
3.2.處理程式
顯然,創建上面的伺服器並沒有比命令列工具提供任何好處。為了開始獲得一些控制權,我們需要引入一個HttpHandler
。
讓我們看看向我們的伺服器添加一個自訂的。我們可以使用SimpleFileServer
的另一種方法createFileHandler()
來建立一個處理程序。假設我們已經有一個像之前創建的伺服器一樣的伺服器,我們可以將新的處理程序附加到它:
HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users"));
server.createContext("/test", handler);
這會導致所有流向127.0.0.1:8080/test
流量都通過我們的新處理程序。
我們可以使用處理程序做更多的事情。例如,讓我們設定一個伺服器來模擬在不同端點上允許和拒絕存取。我們可以使用HttpHandlers.of()
方法來建立允許和拒絕存取的回應:
HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of("Allow", "GET"), "Welcome");
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied");
接下來,我們需要定義一個Predicate
來決定何時回傳每個回應:
Predicate<Request> findAllowedPath = r -> r.getRequestURI()
.getPath().equals("/test/allowed");
只有當我們嘗試存取 URL /test/allowed
時,才會傳回true
。所有其他端點都失敗。
我們現在可以使用HttpHandlers.handleOrElse()
,它接受我們的Predicate
和兩個選項。如果Predicate
通過,則執行第一個,否則執行第二個:
HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);
最後,我們可以像以前一樣使用新的HttpHandler
設定HttpServer
:
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.createContext("/test", handler);
結果是,導航到http://127.0.0.1:8080/test/allowed
顯示文字「 Welcome
」和200
回應。導航到任何其他路徑都會顯示「 Denied
」並顯示401
回應。我們可以根據需要使用它來設定測試環境。然而,潛在的複雜性相當低。
3.3.過濾器
SimpleFileServer
類別的最後一個面向是建立Filter
能力。此Filter
的作用是處理日誌訊息。透過定義我們自己的,我們可以將訊息重定向到我們選擇的OutputStream
。
應用Filter
時,伺服器的建立有所不同。首先,讓我們使用createOutputFilter()
建立Filter
:
Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO);
我們在這裡使用System.out
作為OutputStream
的簡單範例,但我們也可以使用記錄器或任何我們想要的東西。
接下來,我們將HttpServer
類別中的create()
方法與我們剛剛建立的篩選器一起使用:
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10, "/test", handler, filter);
這裡有一些爭論,所以讓我們來看看它們。首先,地址與以前一樣採用InetSocketAddress
的形式。其次,一個整數指定套接字積壓。這是一次允許排隊的最大 TCP 連線數。第三,我們有背景。在這裡,我們指定要處理到達127.0.0.1:8080/test
流量。第四個參數是HttpHandler
,與我們先前創建的類似。最後是我們的Filter
作為第五個參數。
這提供了與我們之前使用處理程序時相同的功能。然而,我們現在可以完全控制日誌輸出。
4。結論
在本文中,我們看到我們可以快速啟動 Java 18 的簡單 Web 伺服器,並且它提供了少量有用的功能。
首先,我們看到透過使用命令列工具jwebserver
我們可以立即啟動並運行伺服器。這個伺服器提供對我們運行它的位置中的檔案和子目錄的讀取存取權。
接下來,我們查看了 API 和可用的新類別,例如SimpleFileServer
。使用此 API,我們可以實現與命令列工具相同的結果,但以程式設計方式實作。我們也可以使用HttpHandler
和Filter
來擴展我們的控制。
與往常一樣,範例的完整程式碼可在 GitHub 上取得。