文件

§Play HTTP API 簡介

§什麼是 EssentialAction?

EssentialAction 是 Play 的 HTTP API 使用的基本函數類型。這與 Java 中的 Action 類型不同,後者是一種接受 Request 並傳回 CompletionStage<Result> 的較高層級類型。在 Java 應用程式中,大多時候你不需要直接使用 EssentialAction,但當撰寫篩選器或與其他低層級 Play API 互動時,它會很有用。

要瞭解 EssentialAction,我們需要瞭解 Play 架構。

Play 的核心很小,周圍環繞著大量有用的 API、服務和結構,讓 Web 程式設計任務更輕鬆。

基本上,Play 的動作 API 抽象具有下列類型

RequestHeader -> byte[] -> Result 

上述類型會取得要求標頭 RequestHeader,然後將要求主體當成 byte[] 取得,並產生一個 Result

現在,這個類型假設將要求主體全部放入記憶體(或磁碟)中,即使你只想從中計算一個值,或最好將它轉發到 Amazon S3 等儲存服務。

我們比較想將要求主體區塊接收為串流,並在必要時能夠逐步處理它們。

我們需要變更第二個箭頭,讓它接收區塊中的輸入,並最終產生一個結果。有一個類型可以做到這一點,它稱為 Accumulator,並採用兩個類型參數。

Accumulator<E,R> 是一種 箭頭 類型,它會以 E 類型的區塊取得輸入,並最終傳回 R。對於我們的 API,我們需要一個 Accumulator,它取得 ByteString 區塊(基本上是位元組陣列的更有效率包裝器),並最終傳回一個 Result。因此,我們稍微修改類型為

RequestHeader -> Accumulator<ByteString, Result>

最後,我們的 Java 類型看起來像

Function<RequestHeader, Accumulator<ByteString, Result>>

這應該讀作:取得要求標頭,取得代表要求主體的 ByteString 區塊,並最終傳回一個 Result。這正是 EssentialAction 的 apply 方法定義的方式

public abstract Accumulator<ByteString, Result> apply(RequestHeader requestHeader);

另一方面,Result 類型可以抽象地視為回應標頭和回應主體

Result(ResponseHeader header, ByteString body)

但是,如果我們想要逐步將回應主體傳送給客戶端,而不用將其全部填入記憶體中,該怎麼辦?我們需要改善我們的類型。我們需要將主體類型從 ByteString 替換為產生 ByteString 塊的類型。

我們已經有了一個類型,稱為 Source<E, ?>,這表示它能夠產生 E 的塊,在我們的案例中是 Source<ByteString, ?>

Result(ResponseHeader header, Source<ByteString, ?> body)

如果我們不必逐步傳送回應,我們仍然可以將整個主體作為一個塊傳送。在實際的 API 中,Play 使用 HttpEntity 包裝類型支援不同的實體類型,它支援串流、分塊和嚴格實體。

§結論

必要的 Play HTTP API 非常簡單

RequestHeader -> Accumulator<ByteString, Result>

讀起來如下:取得 RequestHeader,然後取得 ByteString 塊,並傳回回應。回應包含 ResponseHeaders 和一個主體,它是可轉換為 ByteString 的值塊,以寫入表示在 Source<E, ?> 類型中的 socket。

下一頁:HTTP 篩選器


在這個文件中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交 pull request。有問題或建議要分享嗎?前往 我們的社群論壇 與社群展開對話。