Micronaut HttpRequest 和 HttpResponse

2023-03-02 17:40 更新

如果您需要更多地控制請求處理,您可以編寫一個(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)
}

}
  1. 該方法映射到 URI /hello 并接受 HttpRequest

  2. HttpRequest 用于獲取名為 name 的查詢參數(shù)的值。

  3. 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")
}

}
  1. 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"))
    }
}

}
  1. Mono 是通過引用上下文創(chuàng)建的

  2. 從上下文中檢索請求

使用上下文來檢索請求是響應(yīng)式流的最佳方法,因?yàn)?nbsp;Project Reactor 傳播上下文并且它不依賴于像 ServerRequestContext 這樣的本地線程。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號