Java 18中簡單 Web 伺服器

banq發表於2024-02-26

從 Java 18 開始,我們可以訪問JEP 408中引入的簡單 Web 伺服器。我們可以透過命令列工具和 API 訪問其功能。

簡單 Web 伺服器提供了一個提供靜態檔案服務的基本 Web 伺服器。它被描述為對於測試、原型設計和教育很有用。該伺服器有意使其設定和執行非常簡單,並不旨在與Apache Tomcat或Jetty等功能更齊全的選項競爭或取代。

引入該工具的目標之一是讓開發人員以儘可能少的障礙啟動並執行 Web 開發。

jwebserver命令列工具
啟動伺服器的第一個也是最簡單的方法是使用提供的命令列工具。

單獨使用命令jwebserver就足以啟動伺服器。

如果一切正常,我們會看到以下響應:

$ jwebserver         
Binding to loopback by default. For all interfaces use <font>"-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/<i>

預設情況下,執行命令時所在的目錄就是所提供的目錄,即上例中的/usr 。但是,我們可以使用-d標誌更改目錄:

$ jwebserver -d /opt
Binding to loopback by default. For all interfaces use <font>"-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/<i>

值得注意的是,我們必須在這裡提供絕對路徑。

我們還可以使用-p和 -b標誌更改埠和地址 :

$ jwebserver -b 0.0.0.0 -p 3003    
Serving / and subdirectories on 0.0.0.0 (all interfaces) port 3003
URL http:<font>//192.168.1.1:3003/<i>

執行上述配置會將我們的當前目錄公開給網路上輸出中給出的 IP 地址的任何人。雖然如果我們嘗試傳輸檔案,這可能很有用,但我們應該確保我們樂意首先共享它們。

API
使用簡單 Web 伺服器的第二個選項是 API。透過使用它,我們可以獲得更多的控制權並自定義請求的處理方式。

首先,讓我們使用 API 重新建立命令列 Web 伺服器。

為此,我們將使用SimpleFileServer 類。 我們可以使用這個類來做三件事——建立HttpServer、建立HttpHandler和建立HttpFilter。

首先,我們將使用createFileServer()建立並啟動伺服器:

public static void main(String[] args) {
    InetSocketAddress address = new InetSocketAddress(8080);
    Path path = Path.of(<font>"/");
    HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
    server.start();
}

這裡我們使用 InetSocketAddress類指定了一個地址。我們還可以更改此處地址的其餘部分,而不僅僅是埠。

然後,我們設定了一個 指向我們想要服務的目錄的Path物件。

接下來,我們將這些作為引數以及日誌記錄級別傳遞給createFileServer()。和以前一樣,我們可以配置其中任何一個來滿足我們的需求。生成的 Web 伺服器與使用命令列工具建立的 Web 伺服器相同,可以透過我們的瀏覽器訪問127.0.0.1:8080。

處理程式
顯然,建立上面的伺服器並沒有比命令列工具提供任何好處。為了開始獲得一些控制權,我們需要引入一個HttpHandler。

讓我們看看向我們的伺服器新增一個自定義的。我們可以使用SimpleFileServer的 另一種方法createFileHandler()建立一個處理程式。假設我們已經有一個像之前建立的伺服器一樣的伺服器,我們可以將新的處理程式附加到它:

HttpHandler handler = SimpleFileServer.createFileHandler(Path.of(<font>"/Users"));
server.createContext(
"/test", handler);

這會導致所有流向127.0.0.1:8080/test 的流量都透過我們的新處理程式。

我們可以使用處理程式做更多的事情。例如,讓我們設定一個伺服器來模擬在不同端點上允許和拒絕訪問。我們可以使用HttpHandlers.of()方法來建立允許和拒絕訪問的響應:

HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of(<font>"Allow", "GET"), "Welcome");
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of(
"Deny", "GET"), "Denied");

接下來,我們需要定義一個謂詞來決定何時返回每個響應:

Predicate<Request> findAllowedPath = r -> r.getRequestURI()
  .getPath().equals(<font>"/test/allowed");

僅當我們嘗試訪問 URL /test/allowed時,才會返回true。所有其他端點均失敗。

我們現在可以使用 HttpHandlers.handleOrElse(),它接受我們的 謂詞和兩個選項。如果謂詞透過,則執行第一個,否則執行第二個:

HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);

最後,我們可以像以前一樣使用新的 HttpHandler設定HttpServer:

HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.createContext(<font>"/test", handler);


結果是,導航到http://127.0.0.1:8080/test/allowed顯示文字“ Welcome ”以及200響應。導航到任何其他路徑都會顯示“拒絕”並顯示401響應。我們可以根據需要使用它來設定測試環境。然而,潛在的複雜性相當低。


過濾器
SimpleFileServer類的最後一個方面 是建立 Filter 的能力。該過濾器的作用是處理日誌訊息。透過定義我們自己的,我們可以將訊息重定向到我們選擇的OutputStream 。

應用Filter時,伺服器的建立有所不同 。首先,讓我們使用createOutputFilter()建立過濾器:

Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO);


我們在這裡使用 System.out作為OutputStream的簡單示例 ,但我們也可以使用記錄器或任何我們想要的東西。

接下來,我們將 HttpServer類中的create()方法 與我們剛剛建立的過濾器一起使用:

HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10, <font>"/test", handler, filter);

這裡有一些爭論,所以讓我們來看看它們。首先,地址與以前一樣採用InetSocketAddress的形式。其次,一個整數指定套接字積壓。這是一次允許排隊的最大 TCP 連線數。第三,我們有背景。在這裡,我們指定要處理到達127.0.0.1:8080/test 的流量。第四個引數是HttpHandler,與我們之前建立的類似。最後是我們的過濾器作為第五個引數。

這提供了與我們之前使用處理程式時相同的功能。然而,我們現在可以完全控制日誌輸出。

結論
在本文中,我們看到我們可以快速啟動 Java 18 的簡單 Web 伺服器,並且它提供了少量有用的功能。

首先,我們看到透過使用命令列工具jwebserver我們可以立即啟動並執行伺服器。該伺服器提供對我們執行它的位置中的檔案和子目錄的讀取訪問許可權。

接下來,我們檢視了 API 和可用的新類,例如SimpleFileServer。使用此 API,我們可以實現與命令列工具相同的結果,但以程式設計方式實現。我們還可以使用HttpHandler 和Filter來擴充套件我們的控制。
 

相關文章