Spring WebClient PageImpl Content 缺少字段

Posted

技术标签:

【中文标题】Spring WebClient PageImpl Content 缺少字段【英文标题】:Spring WebClient PageImpl Content is missing field 【发布时间】:2021-01-17 11:40:49 【问题描述】:

我尝试通过 WebClient 从另一个微服务中检索页面。如果我直接向 Postman 请求这个 MS,我会在页面内获得 content 的“类型”等信息。但是,如果我通过webClient 请求MS,“类型”将从content(以及其他一些字段)中消失。内容是抽象类account 的列表,其中'type' 为JsonSubTypes。 有人可以找到错误,为什么是“类型”-attrib。消失了?

回复

来自http://localhost:8080/api/v1/accounts的回复


    "content": [
        
            "type": "savingsBook",
            "id": 108,
            "accountNumber": 99781944,
            ...
        
    ], "pageable": 
        ...
    , "totalPages": ...
    ...

    

来自http://localhost:8081/accounts的回复


    "content": [
        
            "id": 108,
            "accountNumber": 99781944,
            ...
        
    ], "pageable": 
        ...
    , "totalPages": ...
    ...

代码片段:

8080 的账户控制者

@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public <T extends Account> Page<T> getAccounts(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "pageSize", required = false) Integer pageSize, @RequestParam(value = "sortBy", required = false) String sortBy) 
    if (page == null) 
        page = 0;
    
    if (pageSize == null) 
        pageSize = 10;
    
    if (sortBy == null) 
        Page<T> p = accountService.getAccounts(page, pageSize);
        return new PageImpl<T>(p.getContent(), p.getPageable(), p.getTotalElements()) ;

     else 
        Sort sort = Sort.by(sortBy);
        Page<T> p = accountService.getAccounts(page, pageSize, sort);
        return new PageImpl<T>(p.getContent(), p.getPageable(), p.getTotalElements()) ;
    

8081 账户管理员

@GetMapping
public  <T extends Account> Page<T> getAllAccounts(@RequestParam(value = "page", required = false) Integer page, 
                                                   @RequestParam(value = "pageSize", required = false) Integer pageSize,
                                                   @RequestParam(value = "sortBy", required = false) String sortBy)    
     if (page == null) 
         page = 0;
     
     if (pageSize == null) 
         pageSize = 10;
     
     if (sortBy == null) 
         return accountService.getAllAccounts(page, pageSize);
      else 
         return accountService.getAllAccounts(page, pageSize, sortBy);
     

8081 帐户服务

public <T extends Account> Page<T> getAllAccounts(Integer pageNumber, Integer pageSize) 
    ParameterizedTypeReference<CustomPageImpl<T>> typeReference = new ParameterizedTypeReference<CustomPageImpl<T>>();
    System.out.println("Anfrage an: " + addr + "/accounts/");
    System.out.println(client.get().uri("/accounts/").retrieve().bodyToMono(typeReference).block().getContent());
    Page<T> prodData = (CustomPageImpl<T>)(client.get().uri("/accounts/").retrieve().bodyToMono(typeReference).block());
    return prodData;

CustomPageImpl(从另一个 ***-Post 获得)

public class CustomPageImpl<T> extends PageImpl<T> 
    private static final long serialVersionUID = 1L;

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public CustomPageImpl(@JsonProperty("content") List<T> content,
            @JsonProperty("number") int number,
            @JsonProperty("size") int size,
            @JsonProperty("totalElements") Long totalElements,
            @JsonProperty("pageable") JsonNode pageable,
            @JsonProperty("last") boolean last,
            @JsonProperty("totalPages") int totalPages,
            @JsonProperty("sort") JsonNode sort,
            @JsonProperty("first") boolean first,
            @JsonProperty("numberOfElements") int numberOfElements)
        super(content, PageRequest.of(number, size) , totalElements);
    
    public CustomPageImpl(List<T> content, Pageable pageable, long total) 
        super(content, pageable, total);
    

    public CustomPageImpl(List<T> content) 
        super(content);
    

    public CustomPageImpl() 
        super(new ArrayList<>());
    

    

【问题讨论】:

【参考方案1】:

我自己找到了这个问题的答案。

问题在于,Account 是抽象的并且具有 json 子类型。通过用public class CustomPageImpl&lt;T extends Account&gt; extends PageImpl&lt;T&gt; 替换public class CustomPageImpl&lt;T&gt; extends PageImpl&lt;T&gt;,我能够解决这个问题。现在我按计划收到了类型。

【讨论】:

以上是关于Spring WebClient PageImpl Content 缺少字段的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data PageImpl 没有返回正确大小的页面?

Spring - WebClient & RestTemplate

使用 ssl 的 Spring 5 WebClient

禁用 Spring Boot Webclient 日志

spring 5 webclient使用指南

如何使用 Spring5 WebClient 进行异步调用