Spring 使用Flux从单个有效负载获取项目

Spring 使用Flux从单个有效负载获取项目,spring,flux,project-reactor,spring-webflux,Spring,Flux,Project Reactor,Spring Webflux,我有一个查询远程服务的方法。此服务返回一个包含多个项目的有效负载 如何使用Flux和flatMapMany取出这些项目 目前,我的“从服务获取”方法如下所示: public Flux<Stack> listAll() { return this.webClient .get() .uri("/projects") .accept(MediaType.APPLICATION_JSON)

我有一个查询远程服务的方法。此服务返回一个包含多个项目的有效负载

如何使用
Flux
flatMapMany
取出这些项目

目前,我的“从服务获取”方法如下所示:

public Flux<Stack> listAll() {
    return this.webClient
            .get()
            .uri("/projects")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .flatMapMany(response -> response.bodyToFlux(Stack.class));
}
{  
   "data":[  
      {  
         "type":"stacks",
         "id":"1",
         "attributes":{  
            "name":"name_1",
            "title":"title_1",
            "created":"2017-03-31 12:27:59",
            "created_unix":1490916479
         }
      },
      {  
         "type":"stacks",
         "id":"2",
         "attributes":{  
            "name":"name_2",
            "title":"title_2",
            "created":"2017-03-31 12:28:00",
            "created_unix":1490916480
         }
      },
      {  
         "type":"stacks",
         "id":"3",
         "attributes":{  
            "name":"name_3",
            "title":"title_3",
            "created":"2017-03-31 12:28:01",
            "created_unix":1490916481
         }
      }
   ]
}   
这里没有什么特别的,但我认为我的反序列化程序是错误的:

protected Stack deserializeObject(JsonParser jsonParser, DeserializationContext deserializationContext, ObjectCodec objectCodec, JsonNode jsonNode) throws IOException {
    log.info("JsonNode {}", jsonNode);

    return Stack.builder()
            .id(nullSafeValue(jsonNode.findValue("id"), String.class))
            .name(nullSafeValue(jsonNode.findValue("name"), String.class))
            .title(nullSafeValue(jsonNode.findValue("title"), String.class))
            .created(nullSafeValue(jsonNode.findValue("created"), String.class))
            .build();
}
我注意到发生的事情是第一个对象被正确序列化,但之后它似乎再次被序列化,而不是负载中的下一个对象

输入的有效负载遵循标准JSON API规范,如下所示:

public Flux<Stack> listAll() {
    return this.webClient
            .get()
            .uri("/projects")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .flatMapMany(response -> response.bodyToFlux(Stack.class));
}
{  
   "data":[  
      {  
         "type":"stacks",
         "id":"1",
         "attributes":{  
            "name":"name_1",
            "title":"title_1",
            "created":"2017-03-31 12:27:59",
            "created_unix":1490916479
         }
      },
      {  
         "type":"stacks",
         "id":"2",
         "attributes":{  
            "name":"name_2",
            "title":"title_2",
            "created":"2017-03-31 12:28:00",
            "created_unix":1490916480
         }
      },
      {  
         "type":"stacks",
         "id":"3",
         "attributes":{  
            "name":"name_3",
            "title":"title_3",
            "created":"2017-03-31 12:28:01",
            "created_unix":1490916481
         }
      }
   ]
}   
我是根据

任何关于我哪里出了错的帮助都会很棒


干杯

json与模型类(即堆栈)不完全匹配。与Stack一起创建另一个类似的类

public class Data {
  List<Stack> data;
   // Getters and Setters.... 
}
Mono<Data> listMono = webClient
                .get()
                .uri("/product/projects")
                .exchange()
                .flatMap(clientResponse -> clientResponse.bodyToMono(Data.class));
公共类数据{
列出数据;
//能手和二传手。。。。
}
现在,在您的webclient中,您可以这样做

public class Data {
  List<Stack> data;
   // Getters and Setters.... 
}
Mono<Data> listMono = webClient
                .get()
                .uri("/product/projects")
                .exchange()
                .flatMap(clientResponse -> clientResponse.bodyToMono(Data.class));
Mono-listMono=webClient
.get()
.uri(“/product/projects”)
.exchange()
.flatMap(clientResponse->clientResponse.bodytomino(Data.class));

现在,如果执行
listMono.block()
操作,您将获得包含所有堆栈对象的数据对象。

您的json与您的模型类(即堆栈)不完全匹配。与Stack一起创建另一个类似的类

public class Data {
  List<Stack> data;
   // Getters and Setters.... 
}
Mono<Data> listMono = webClient
                .get()
                .uri("/product/projects")
                .exchange()
                .flatMap(clientResponse -> clientResponse.bodyToMono(Data.class));
公共类数据{
列出数据;
//能手和二传手。。。。
}
现在,在您的webclient中,您可以这样做

public class Data {
  List<Stack> data;
   // Getters and Setters.... 
}
Mono<Data> listMono = webClient
                .get()
                .uri("/product/projects")
                .exchange()
                .flatMap(clientResponse -> clientResponse.bodyToMono(Data.class));
Mono-listMono=webClient
.get()
.uri(“/product/projects”)
.exchange()
.flatMap(clientResponse->clientResponse.bodytomino(Data.class));

现在,如果执行
listMono.block()
操作,您将获得包含所有堆栈对象的数据对象。

我想我已经解决了这个问题,仍然使用了
通量

public Flux<Stack> listAllStacks() {
    return this.webClient
            .get()
            .uri("/naut/projects")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .flatMap(response -> response.toEntity(String.class))
            .flatMapMany(this::transformPayloadToStack);
}
它返回一个
通量
。多亏了这个库,我也不需要创建一堆域,我仍然可以使用我的简单
Stack
POJO

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@Type("stacks")
public class Stack {
    @com.github.jasminb.jsonapi.annotations.Id
    String id;
    String name;
    String title;
    String created;
}
这又是从控制器调用的

@GetMapping("/stacks")
@ResponseBody
public Flux<Stack> findAll() {
    return this.stackService.listAllStacks();
}
@GetMapping(“/stacks”)
@应答器
公共流量findAll(){
返回此.stackService.listAllStacks();
}

我还没有测试这是否阻塞,但似乎工作正常

我想我还是用
通量解决了这个问题

public Flux<Stack> listAllStacks() {
    return this.webClient
            .get()
            .uri("/naut/projects")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .flatMap(response -> response.toEntity(String.class))
            .flatMapMany(this::transformPayloadToStack);
}
它返回一个
通量
。多亏了这个库,我也不需要创建一堆域,我仍然可以使用我的简单
Stack
POJO

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@Type("stacks")
public class Stack {
    @com.github.jasminb.jsonapi.annotations.Id
    String id;
    String name;
    String title;
    String created;
}
这又是从控制器调用的

@GetMapping("/stacks")
@ResponseBody
public Flux<Stack> findAll() {
    return this.stackService.listAllStacks();
}
@GetMapping(“/stacks”)
@应答器
公共流量findAll(){
返回此.stackService.listAllStacks();
}

我还没有测试这是否阻塞,但似乎工作正常

此Web服务是否返回流量或仅返回一个实体?此Web服务是否返回流量或仅返回一个实体?感谢您的回答,我们将尝试并报告它。你能解释一下为什么我链接的例子会有变化吗?它也从github获得了一个有效载荷。从我所读到的所有内容来看,除了测试之外,你不应该在任何事情上阻塞?关于阻塞,你是对的,在执行反应式编程时不建议执行阻塞。但是在测试中,没有其他方法可以在没有块的情况下执行代码。关于为什么它会在有效载荷中得到一个项目,嗯,这有点棘手,需要进行更多的调查。但是是的,这很奇怪,为什么它会得到第一个项目。谢谢你的回答,我会给它一个机会,并报告回来。你能解释一下为什么我链接的例子会有变化吗?它也从github获得了一个有效载荷。从我所读到的所有内容来看,除了测试之外,你不应该在任何事情上阻塞?关于阻塞,你是对的,在执行反应式编程时不建议执行阻塞。但是在测试中,没有其他方法可以在没有块的情况下执行代码。关于为什么它会在有效载荷中得到一个项目,嗯,这有点棘手,需要进行更多的调查。但是是的,这很奇怪,为什么它会获取第一个项目。