簡體   English   中英

編寫“反應式”WebFlux controller

[英]Writing 'reactive' WebFlux controller

我正在嘗試將 WebMVC controller 轉換為 WebFlux controller 返回Mono<Resource>

舊的WebMVC controller 如下所示。

@GetMapping("/resources/{id}")
public ResponseEntity<Resource> getCustomer(@RequestParam String id) {
    if(id.length != 10) {
        // set ResponseEntity status 400 and then return it
    }

    val resource = resourceService.getResourceById(id);    
    return ResponseEntity.ok().body(resource);
}

我怎樣才能讓if塊與Reactive Programming更兼容?

如果您使用的是功能端點,則可以執行類似的操作。

public Mono<ServerResponse> getCustomer(ServerRequest serverRequest) {

  if (serverRequest.pathVariable("id").length() != 10) {

    return ServerResponse
        .status(400)
        .build();

  } else {

    return ServerResponse
        .ok()
        .body(
            resourceService.getResourceById(serverRequest.pathVariable("id")),
            Resource.class
        );

  }

}

上面提到的對我來說更具可讀性。 但是你可以從Mono.just(serverRequest.pathVariable("id"))開始,如果你真的想在方法中維護 stream ,如下所示。

return Mono.just(serverRequest.pathVariable("id"))
  .filter(id -> id.length() == 10)
  .flatMap(resourceService::getResourceById)
  .flatMap(resource -> ServerResponse
      .ok()
      .body(
          resourceService.getResourceById(serverRequest.pathVariable("id")),
          Resource.class
      )
  )
  .switchIfEmpty(ServerResponse.status(400).build());

同樣,如果您使用帶注釋的控制器,則類似下面的內容似乎更具可讀性(對我來說:))。

@GetMapping(path = "/resources/{id}")
public ResponseEntity<Mono<Resource>> getCustomer(@PathVariable String id) {

  if (id.length() != 10) {

    return ResponseEntity
            .status(400)
            .build();

  } else {

    return ResponseEntity
        .ok()
        .body(resourceService
            .getResourceById(id));

  }

}

官方文檔是一個足夠好的參考:文檔中的兩個相關部分

  1. https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-controller
  2. https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-fn

您需要為 webflux 功能流創建處理程序、路由器

@Component

公共 class SampleHandlerFunction {

public Mono<ServerResponse> flux(ServerRequest serverRequest) {

    return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(
                    Flux.just(1, 2, 3, 4)
                            .log(), Integer.class
            );
}

public Mono<ServerResponse> mono(ServerRequest serverRequest) {

    return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(
                    Mono.just(1)
                            .log(), Integer.class
            );
}

路由器

@Configuration

公共 class RouterFunctionConfig {

@Bean
public RouterFunction<ServerResponse> route(com.Reactive.SpringReactive.handler.SampleHandlerFunction handlerFunction){

    return RouterFunctions
            .route(GET("/functional/flux").and(accept(MediaType.APPLICATION_JSON)),handlerFunction::flux)
            .andRoute(GET("/functional/mono").and(accept(MediaType.APPLICATION_JSON)),handlerFunction::mono);

}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM