繁体   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