java问题:返回类型responseentity的流量

t8e9dugd  于 2021-06-26  发布在  Java
关注(0)|答案(2)|浏览(467)

我有下面的片段,我想从 ResponseEntity<Response> :

@GetMapping("/{id}")
public Mono<ResponseEntity<Response>> findByDocumentClient(@PathVariable("id") String document){
    return Mono.just(new ResponseEntity<>(new Response(technomechanicalService.findByDocumentClient(document), HttpStatus.OK.value(), null), 
                            HttpStatus.OK))
            .onErrorResume(error -> {
                return Mono.just(new ResponseEntity<>(new Response(null, HttpStatus.BAD_REQUEST.value(), error.getMessage()), 
                                        HttpStatus.BAD_REQUEST));
            });
}

响应对象如下:

public class Response{
    private Object body;
    private Integer status;
    private String descStatus;

    public Response(Object body, Integer status, String descStatus) {
        this.body = body;
        this.status = status;
        this.descStatus = descStatus;
    }
}

当使用postman的get方法时,服务将响应以下内容:

{
    "body": {
        "scanAvailable": true,
        "prefetch": -1
    },
    "status": 200,
    "descStatus": null
}

为什么会产生这种React?为什么对象列表没有响应?

ac1kyiln

ac1kyiln1#

同意@toerktumlare的回答。比较全面。
@胡安大卫bá根据你的回答(最好是一个评论),你想要的似乎是 technomechanicalService.findByDocumentClient(document) 结果为 body 在一个 Response 对象。
如果是这样,您可以使用fluxapi collectList() 接线员。
示例代码:

@GetMapping("/{id}")
public Mono<ResponseEntity<Response>> findByDocumentClient(@PathVariable("id") String document) {
    return technomechanicalService.findByDocumentClient(document)
        .collectList()
        .map(
            listOfDocuments -> {
              return new ResponseEntity<>(
                  new Response(listOfDocuments, HttpStatus.OK.value(), null), HttpStatus.OK);
            }
        )
        .onErrorResume(
            error -> {
              return Mono.just(new ResponseEntity<>(
                  new Response(null, HttpStatus.BAD_REQUEST.value(), error.getMessage()),
                  HttpStatus.BAD_REQUEST));
            }
        );
}
nwlls2ji

nwlls2ji2#

这是因为您试图强制地编写代码(传统的java),并且您正在序列化mono,而不是从数据库返回的实际值。您应该在reactor/webflux使用这种类型的开发时进行功能性编码。
Mono<T> 是一个 producer 当有人订阅时产生元素。发起呼叫的用户,在本例中是客户机/浏览器。
这就是为什么你需要返回一个 Mono<ResponseEntity> 因为当客户 subscribes 它会发出 ResponseEntity 让我们看看你的代码:

@GetMapping("/{id}")
public Mono<ResponseEntity<Response>> findByDocumentClient(@PathVariable("id") String document){
    return Mono.just(new ResponseEntity<>(new Response(technomechanicalService.findByDocumentClient(document), HttpStatus.OK.value(), null), 
                            HttpStatus.OK))
            .onErrorResume(error -> {
                return Mono.just(new ResponseEntity<>(new Response(null, HttpStatus.BAD_REQUEST.value(), error.getMessage()), 
                                        HttpStatus.BAD_REQUEST));
            });
}

你要做的第一件事,就是把你的回答直接放到 Mono 使用 Mono#just . 在webflux a中 Mono 是一种可以发出某种信息的东西,一旦你在其中放入某种信息,你也会告诉服务器,它可以自由地更改执行该执行的线程。所以我们基本上想进入一个 Mono 尽可能快,这样我们就可以利用webflux线程不可知的能力。
那么这一行:

technomechanicalService.findByDocumentClient(document)

返回一个 Mono<T> 你把它放在你的 Response 身体。所以它试图将其序列化为json,而您认为它需要内部 Value 并序列化它实际上是序列化 Mono .
因此,让我们重写您的代码*我暂时不做错误处理,因为我是在移动设备上写的:

@GetMapping("/{id}")
public Mono<ServerResponse> findByDocumentClient(@PathVariable("id") String document){
    // We place our path variable in a mono so we can leverage 
    // webflux thread agnostic abilities
    return Mono.just(document)
               // We access the value by flatMapping and do our call to 
               // the database which will return a Mono<T>
               .flatMap(doc -> technomechanicalService.findByDocumentClient(doc)
                   // We flatmap again over the db response to a ServerResponse
                   // with the db value as the body
                   .flatMap(value -> ServerResponse.ok().body(value)));
}

所有这些都是超级基础React堆/webflux的东西。我想这是你第一次使用webflux。如果是这样的话,我强烈建议你通过reactor,开始了解基础知识的工作原理,否则你将很难理解reactor,以后还要理解webflux。

相关问题