春季WebFlux发布问题

时间:2018-10-03 15:50:38

标签: spring-boot spring-webflux

我正在使用WebClient进行API发布,但未返回任何内容。我假设线程保持打开状态并且没有完成,因为我可以使用块来获取所需的内容,但是对于WebClient和异步对象我还是很陌生,所以我不确定100%。

具体地说,我有这种方法:

public Mono<AppDto> applicationPost(AppDto dto){    
   return webClient.post()
            .uri("/api/doStuff")
            .contentType(MediaType.APPLICATION_JSON)
            .body(MonoConverter.appDtoToMono(dto), String.class)
            .exchange()
            .flatMap(clientResponse -> clientResponse.bodyToMono(Map.class))
            .map(MonoConverter::mapValueToAppDto);
}

MonoConverter在哪里对映射值进行一些转换,因此应该无关紧要。上面的代码返回了202 Accepted,但是没有返回值或没有命中我的mapValueToAppDto方法。但是,下面的方法确实有效:

public Mono<AppDto> applicationPost(AppDto dto){
    Map map = webClient.post()
            .uri("/api/doStuff")
            .contentType(MediaType.APPLICATION_JSON)
            .body(MonoConverter.appDtoToMono(dto), String.class)
            .exchange()
            .flatMap(clientResponse -> clientResponse.bodyToMono(Map.class))
            .block();
    return Mono.just(MonoConverter.mapValueToAppDto(map));
}

我假设这是可行的,因为它使用了block,但是我拥有的get方法却以类似的方式起作用:

public Mono<AppDto> applicationGetOne(String appId){
    return webClient.get()
            .uri("/api/getOne/{0}",appId)
            .exchange()
            .flatMap(clientResponse -> clientResponse.bodyToMono(Map.class))
            .map(MonoConverter::mapValueToAppDto);
}

我更喜欢使用第一个代码段,因为它不使用block,并且更简单,并且格式与我的其他方法相同。

有人知道为什么第一个不工作或不知道如何使它工作吗?

1 个答案:

答案 0 :(得分:0)

我找到了出现此问题的原因。实际上与我的控制器有关  (D'哦!)。对于post方法,我具有绑定错误的验证,因此我只是返回一个ResponseEntity而不提供其类型。因此,我在ResponseEntity中添加了键入内容,从而解决了该问题。

例如:

@PostMapping(value="/post")
public ResponseEntity addThing(@Validated @RequestBody AppDto dto, BindingResult result){
    ...
}

以及解决方法:

@PostMapping(value="/post")
public ResponseEntity<Mono<?>> addThing(@Validated @RequestBody AppDto dto, BindingResult result){
    ...
}

我假设因为一开始没有指定类型,所以没有使用单声道响应的线程,所以我从没有得到响应,但是通过声明类型,Spring知道使用单声道允许它完成。