§操作结果
§更改默认 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
尚未完全支持。
可以为 Source
、InputStream
、文件和 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);
}
下一步:会话和闪存范围
发现文档中的错误? 此页面源代码可在此处找到 此处。 在阅读 文档指南 后,请随时贡献拉取请求。 有问题或建议要分享? 前往 我们的社区论坛 与社区交流。