如果您需要更多地控制請求處理,您可以編寫一個(gè)方法來接收完整的 HttpRequest。
事實(shí)上,有幾個(gè)更高級別的接口可以綁定到控制器方法參數(shù)。這些包括:
表 1. 可綁定的 Micronaut 接口
接口 |
描述 |
示例 |
HttpRequest
|
完整的 HttpRequest
|
String hello(HttpRequest request)
|
HttpHeaders
|
請求中存在的所有 HTTP 標(biāo)頭
|
String hello(HttpHeaders headers)
|
HttpParameters
|
請求中存在的所有 HTTP 參數(shù)(來自 URI 變量或請求參數(shù))
|
String hello(HttpParameters params)
|
Cookies
|
請求中存在的所有 Cookie
|
String hello(Cookies cookies)
|
如果需要請求主體,則 HttpRequest 應(yīng)該聲明為參數(shù)化的具體泛型類型,例如HttpRequest<MyClass> 請求。否則可能無法從請求中獲得正文。
此外,為了完全控制發(fā)出的 HTTP 響應(yīng),您可以使用返回 MutableHttpResponse 的 HttpResponse 類的靜態(tài)工廠方法。
以下示例使用 HttpRequest 和 HttpResponse 對象實(shí)現(xiàn)了前面的 MessageController 示例:
請求和響應(yīng)示例
Java |
Groovy |
Kotlin |
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.context.ServerRequestContext;
import reactor.core.publisher.Mono;
@Controller("/request")
public class MessageController {
@Get("/hello") // (1)
public HttpResponse<String> hello(HttpRequest<?> request) {
String name = request.getParameters()
.getFirst("name")
.orElse("Nobody"); // (2)
return HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo"); // (3)
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
@Controller("/request")
class MessageController {
@Get("/hello") // (1)
HttpResponse<String> hello(HttpRequest<?> request) {
String name = request.parameters
.getFirst("name")
.orElse("Nobody") // (2)
HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo") // (3)
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
import reactor.util.context.ContextView
@Controller("/request")
class MessageController {
@Get("/hello") // (1)
fun hello(request: HttpRequest<*>): HttpResponse<String> {
val name = request.parameters
.getFirst("name")
.orElse("Nobody") // (2)
return HttpResponse.ok("Hello $name!!")
.header("X-My-Header", "Foo") // (3)
}
}
|
該方法映射到 URI /hello 并接受 HttpRequest
HttpRequest 用于獲取名為 name 的查詢參數(shù)的值。
HttpResponse.ok(T) 方法返回帶有文本正文的 MutableHttpResponse。名為 X-My-Header 的標(biāo)頭也會添加到響應(yīng)中。
HttpRequest 也可以通過 ServerRequestContext 從靜態(tài)上下文中獲得。
使用 ServerRequestContext
Java |
Groovy |
Kotlin |
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.context.ServerRequestContext;
import reactor.core.publisher.Mono;
@Controller("/request")
public class MessageController {
@Get("/hello-static") // (1)
public HttpResponse<String> helloStatic() {
HttpRequest<?> request = ServerRequestContext.currentRequest() // (1)
.orElseThrow(() -> new RuntimeException("No request present"));
String name = request.getParameters()
.getFirst("name")
.orElse("Nobody");
return HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo");
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
@Controller("/request")
class MessageController {
@Get("/hello-static") // (1)
HttpResponse<String> helloStatic() {
HttpRequest<?> request = ServerRequestContext.currentRequest() // (1)
.orElseThrow(() -> new RuntimeException("No request present"))
String name = request.parameters
.getFirst("name")
.orElse("Nobody")
HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo")
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
import reactor.util.context.ContextView
@Controller("/request")
class MessageController {
@Get("/hello-static") // (1)
fun helloStatic(): HttpResponse<String> {
val request: HttpRequest<*> = ServerRequestContext.currentRequest<Any>() // (1)
.orElseThrow { RuntimeException("No request present") }
val name = request.parameters
.getFirst("name")
.orElse("Nobody")
return HttpResponse.ok("Hello $name!!")
.header("X-My-Header", "Foo")
}
}
|
ServerRequestContext 用于檢索請求。
通常 ServerRequestContext 在反應(yīng)流中可用,但推薦的方法是將請求作為參數(shù)使用,如前一個(gè)示例所示。如果下游方法需要請求,則應(yīng)將其作為參數(shù)傳遞給這些方法。在某些情況下,上下文不會傳播,因?yàn)槠渌€程用于發(fā)出數(shù)據(jù)。
Project Reactor 用戶使用 ServerRequestContext 的替代方法是使用 Project Reactor 的上下文功能來檢索請求。由于 Micronaut 框架使用 Project Reactor 作為其默認(rèn)的反應(yīng)流實(shí)現(xiàn),因此 Project Reactor 的用戶可以通過能夠在上下文中訪問請求而受益。例如:
使用 Project Reactor 上下文
Java |
Groovy |
Kotlin |
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.context.ServerRequestContext;
import reactor.core.publisher.Mono;
@Controller("/request")
public class MessageController {
@Get("/hello-reactor")
public Mono<HttpResponse<String>> helloReactor() {
return Mono.deferContextual(ctx -> { // (1)
HttpRequest<?> request = ctx.get(ServerRequestContext.KEY); // (2)
String name = request.getParameters()
.getFirst("name")
.orElse("Nobody");
return Mono.just(HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo"));
});
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
@Controller("/request")
class MessageController {
@Get("/hello-reactor")
Mono<HttpResponse<String>> helloReactor() {
Mono.deferContextual(ctx -> { // (1)
HttpRequest<?> request = ctx.get(ServerRequestContext.KEY) // (2)
String name = request.parameters
.getFirst("name")
.orElse("Nobody")
Mono.just(HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo"))
})
}
}
|
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.context.ServerRequestContext
import reactor.core.publisher.Mono
import reactor.util.context.ContextView
@Controller("/request")
class MessageController {
@Get("/hello-reactor")
fun helloReactor(): Mono<HttpResponse<String>?>? {
return Mono.deferContextual { ctx: ContextView -> // (1)
val request = ctx.get<HttpRequest<*>>(ServerRequestContext.KEY) // (2)
val name = request.parameters
.getFirst("name")
.orElse("Nobody")
Mono.just(HttpResponse.ok("Hello $name!!")
.header("X-My-Header", "Foo"))
}
}
}
|
Mono 是通過引用上下文創(chuàng)建的
從上下文中檢索請求
使用上下文來檢索請求是響應(yīng)式流的最佳方法,因?yàn)?nbsp;Project Reactor 傳播上下文并且它不依賴于像 ServerRequestContext 這樣的本地線程。
更多建議: