Micronaut HttpRequest 和 HttpResponse

2023-03-02 17:40 更新

如果您需要更多地控制請(qǐng)求處理,您可以編寫一個(gè)方法來(lái)接收完整的 HttpRequest。

事實(shí)上,有幾個(gè)更高級(jí)別的接口可以綁定到控制器方法參數(shù)。這些包括:

表 1. 可綁定的 Micronaut 接口
接口 描述 示例

HttpRequest

完整的 HttpRequest

String hello(HttpRequest request)

HttpHeaders

請(qǐng)求中存在的所有 HTTP 標(biāo)頭

String hello(HttpHeaders headers)

HttpParameters

請(qǐng)求中存在的所有 HTTP 參數(shù)(來(lái)自 URI 變量或請(qǐng)求參數(shù))

String hello(HttpParameters params)

Cookies

請(qǐng)求中存在的所有 Cookie

String hello(Cookies cookies)

如果需要請(qǐng)求主體,則 HttpRequest 應(yīng)該聲明為參數(shù)化的具體泛型類型,例如HttpRequest<MyClass> 請(qǐng)求。否則可能無(wú)法從請(qǐng)求中獲得正文。

此外,為了完全控制發(fā)出的 HTTP 響應(yīng),您可以使用返回 MutableHttpResponse 的 HttpResponse 類的靜態(tài)工廠方法。

以下示例使用 HttpRequest 和 HttpResponse 對(duì)象實(shí)現(xiàn)了前面的 MessageController 示例:

請(qǐng)求和響應(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)頭也會(huì)添加到響應(yīng)中。

HttpRequest 也可以通過(guò) 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 用于檢索請(qǐng)求。

通常 ServerRequestContext 在反應(yīng)流中可用,但推薦的方法是將請(qǐng)求作為參數(shù)使用,如前一個(gè)示例所示。如果下游方法需要請(qǐng)求,則應(yīng)將其作為參數(shù)傳遞給這些方法。在某些情況下,上下文不會(huì)傳播,因?yàn)槠渌€程用于發(fā)出數(shù)據(jù)。

Project Reactor 用戶使用 ServerRequestContext 的替代方法是使用 Project Reactor 的上下文功能來(lái)檢索請(qǐng)求。由于 Micronaut 框架使用 Project Reactor 作為其默認(rèn)的反應(yīng)流實(shí)現(xiàn),因此 Project Reactor 的用戶可以通過(guò)能夠在上下文中訪問(wèn)請(qǐng)求而受益。例如:

使用 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 是通過(guò)引用上下文創(chuàng)建的

  2. 從上下文中檢索請(qǐng)求

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


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)