文件

§處理結果

§變更預設的 Content-Type

結果內容類型會自動從您指定為回應主體的 Java 值推論出來。

例如

Result textResult = ok("Hello World!");

將自動設定 Content-Type 標頭為 text/plain,而

JsonNode json = Json.toJson(object);
Result jsonResult = ok(json);

將設定 Content-Type 標頭為 application/json

這相當實用,但有時您會想要變更它。只要對結果使用 as(newContentType) 方法,即可建立一個具有不同 Content-Type 標頭的新類似結果

Result htmlResult = ok("<h1>Hello World!</h1>").as("text/html");

或甚至更好,使用

Result htmlResult = ok("<h1>Hello World!</h1>").as(MimeTypes.HTML);

§處理 HTTP 標頭

您也可以將任何 HTTP 標頭新增 (或更新) 至結果

public Result index() {
  return ok("<h1>Hello World!</h1>")
      .as(MimeTypes.HTML)
      .withHeader(CACHE_CONTROL, "max-age=3600")
      .withHeader(ETAG, "some-etag-calculated-value");
}

請注意,設定 HTTP 標頭會自動捨棄先前值 (如果存在於原始結果中)。

§設定和捨棄 Cookie

Cookie 只是 HTTP 標頭的特殊形式,但 Play 提供一組輔助程式,讓它更容易使用。

您可以使用輕鬆地將 Cookie 新增至 HTTP 回應

public Result index() {
  return ok("<h1>Hello World!</h1>")
      .as(MimeTypes.HTML)
      .withCookies(Cookie.builder("theme", "blue").build());
}

如果您需要設定更多詳細資料,包括路徑、網域、到期日、是否安全,以及是否應設定 HTTP only 標記,您可以使用超載方法執行此操作

public Result index() {
  return ok("<h1>Hello World!</h1>")
      .as(MimeTypes.HTML)
      .withCookies(
          Cookie.builder("theme", "blue")
              .withMaxAge(Duration.ofSeconds(3600))
              .withPath("/some/path")
              .withDomain(".example.com")
              .withSecure(false)
              .withHttpOnly(true)
              .withSameSite(Cookie.SameSite.STRICT)
              .build());
}

捨棄先前儲存在 Web 瀏覽器的 Cookie

public Result index() {
  return ok("<h1>Hello World!</h1>").as(MimeTypes.HTML).discardingCookie("theme");
}

如果您在設定 Cookie 時設定路徑或網域,請務必在捨棄 Cookie 時設定相同的路徑或網域,因為瀏覽器僅會在名稱、路徑和網域相符時捨棄它。

§變更基於文字的 HTTP 回應的字元集

對於基於文字的 HTTP 回應,正確處理字元集非常重要。Play 會為您處理,並預設使用 utf-8 (請參閱 為何使用 utf-8).

字元集用於將文字回應轉換為對應的位元組,以透過網路 Socket 傳送,並使用適當的 ;charset=xxx 延伸更新 Content-Type 標頭。

當您產生 Result 值時,可以指定編碼

public Result index() {
  return ok("<h1>Hello World!</h1>", "iso-8859-1")
      .as("text/html; charset=iso-8859-1");
}

§範圍結果

Play 支援 RFC 7233 的一部分,其中定義了範圍要求和部分回應的工作方式。如果要求中存在可滿足的 Range 標頭,它會讓您傳送 206 Partial Content。它也會為傳送的 Result 傳回 Accept-Ranges: bytes

注意:除了已進行一些剖析以更好地處理多個範圍外,multipart/byteranges 尚未完全支援。

範圍結果可以為 SourceInputStream、檔案和 Path 產生。請參閱 RangeResult API 文件以查看所有可用的方法。例如

public Result index(Http.Request request) {
  String content = "This is the full content!";
  InputStream input = getInputStream(content);
  return RangeResults.ofStream(request, input, content.length());
}

或對於 Source

public Result index(Http.Request request) {
  String content = "This is the full content!";
  Source<ByteString, NotUsed> source = sourceFrom(content);
  return RangeResults.ofSource(
      request, (long) content.length(), source, "file.txt", MimeTypes.TEXT);
}

如果要求的 Range 無法滿足,例如,如果要求的 Range 標頭欄位中的範圍與所選資源的目前範圍沒有重疊,則會傳回 HTTP 狀態 416(無法滿足範圍)。

也可以預先尋找 Source 的特定位置,以更有效率地傳送範圍結果。為此,您可以提供一個函式,其中會發生預先尋找

public Result index(Http.Request request) {
  String content = "This is the full content!";
  return RangeResults.ofSource(
      request,
      (long) content.length(),
      offset ->
          new RangeResults.SourceAndOffset(offset, sourceFrom(content).drop(offset)),
      "file.txt",
      MimeTypes.TEXT);
}

下一步:Session 和 Flash 範圍


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