文档

§操作结果

§更改默认 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 仅标志,您可以使用重载方法来完成此操作

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)。

字符集用于将文本响应转换为相应的字节以通过网络套接字发送,以及使用正确的 ;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);
}

下一步:会话和闪存范围


发现文档中的错误? 此页面源代码可在此处找到 此处。 在阅读 文档指南 后,请随时贡献拉取请求。 有问题或建议要分享? 前往 我们的社区论坛 与社区交流。