Java 使用Jackson自定义反序列化器通过RestTemplate解析Spring Boot 2.1.0页面响应

Java 使用Jackson自定义反序列化器通过RestTemplate解析Spring Boot 2.1.0页面响应,java,spring,spring-boot,jackson,Java,Spring,Spring Boot,Jackson,请帮助我解析Spring响应。我正在尝试使用Jackson自定义反序列化程序。REST服务器是在SpringBoot2.1.0.RELEASE上实现的,它引入了SpringDataCommons 2.1.2和Jackson 2.9.7。服务器端点将输出块作为页面返回。在SpringBootVersion1.5.x中工作的反序列化程序现在抛出异常,因为2.1响应非常不同。以下是来自spring boot 2.1 REST端点的数据: { "content": [ "3" ], "pag

请帮助我解析Spring响应。我正在尝试使用Jackson自定义反序列化程序。REST服务器是在SpringBoot2.1.0.RELEASE上实现的,它引入了SpringDataCommons 2.1.2和Jackson 2.9.7。服务器端点将输出块作为页面返回。在SpringBootVersion1.5.x中工作的反序列化程序现在抛出异常,因为2.1响应非常不同。以下是来自spring boot 2.1 REST端点的数据:

{
   "content": [ "3" ],
   "pageable": {
     "sort": {
       "sorted": false,
       "unsorted": true,
       "empty": true
     },
     "offset": 0,
     "pageSize": 20,
     "pageNumber": 0,
     "unpaged": false,
     "paged": true
  },
  "last": true,
  "totalPages": 1,
  "totalElements": 1,
  "size": 20,
  "number": 0,
  "numberOfElements": 1,
  "first": true,
  "sort": {
    "sorted": false,
    "unsorted": true,
    "empty": true
  },
  "empty": false
}
我试图遵循这些SO答案的建议,只要我忽略排序字段,客户机就会工作:

当我尝试解析排序字段时,下面的代码会产生一个异常:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `org.mypackage.RestPageResponse`, 
problem: argument type mismatch at [Source: (String)
"{ "content":["1","2","3"],"first":true,"last":false,  "number":0,"numberOfElements":3,"size":3,"totalElements":90,"totalPages":30,  "sort":[{"direction":"ASC","property":"name","ignoreCase":false,"nullHandling":"NATIVE","ascending":true,"descending":false}]  }"; 
line: 1, column: 260]
下面是响应的Java类(域模型)。我在这个类中将排序数据建模为一个字段,这可能是错误的,应该有一种方法将它以可分页对象的形式传递给超类

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class RestPageResponse<T> extends PageImpl<T> {

    private static final long serialVersionUID = 5835593096562217592L;

    private Sort sort;

    public RestPageResponse() {
        super(new ArrayList<T>());
    }

    public RestPageResponse(List<T> content) {
        super(content);
    }

    public RestPageResponse(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    /*
     * https://stackoverflow.com/questions/34647303/spring-resttemplate-with-paginated-api
     */
    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public RestPageResponse(//
        @JsonProperty("content") List<T> content, // PageImpl
        @JsonProperty("number") int number, // PageImpl
        @JsonProperty("size") int size, // PageImpl
        @JsonProperty("totalElements") long totalElements, // PageImpl
        @JsonProperty("pageable") JsonNode pageable, //
        @JsonProperty("sort") JsonNode sort, //
        @JsonProperty("totalPages") int totalPages, // computed
        @JsonProperty("first") boolean first, // computed
        @JsonProperty("last") boolean last, // computed
        @JsonProperty("empty") boolean empty, // computed
        @JsonProperty("numberOfElements") int numberOfElements // computed
    ) {
    super(content, PageRequest.of(number, size), totalElements);
    }

    @Override
    public Sort getSort() {
        return sort;
    }

    @JsonDeserialize(using = CustomSortDeserializer.class)
    public void setSort(Sort sort) {
        this.sort = sort;
    }

}
如果我从响应模型中删除@JsonDeserialize注释,那么解析工作正常,但排序字段内容被丢弃


为什么这么难?春天的人们说“使用HATEOAS”,我一点也不明白。提前谢谢。

这是我为使排序工作正常所做的

类,该类使用Rest模板使用API

package br.com.ironforge.springboottutorial.javaclient;

import java.util.Arrays;
import java.util.List;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import br.com.ironforge.springboottutorial.model.PageableResponse;
import br.com.ironforge.springboottutorial.model.Student;

public class JavaSpringClientTest {

    public static void main(String[] args) {

        RestTemplate restTemplate = new RestTemplateBuilder().rootUri("http://localhost:8080/v1/protected/students")
                .basicAuthentication("username", "password").build();

        ResponseEntity<PageableResponse<Student>> exchange = restTemplate.exchange("/?sort=id,asc", HttpMethod.GET, null,
                new ParameterizedTypeReference<PageableResponse<Student>>() {
                });
        System.out.println(exchange.getBody().getContent());
    }
}
package br.com.ironferge.springboottotutorial.javaclient;
导入java.util.array;
导入java.util.List;
导入org.springframework.boot.web.client.RestTemplateBuilder;
导入org.springframework.core.ParameterizedTypeReference;
导入org.springframework.http.HttpMethod;
导入org.springframework.http.ResponseEntity;
导入org.springframework.web.client.rest模板;
导入br.com.ironferge.springboottotutorial.model.PageableResponse;
导入br.com.ironferge.springboottotutorial.model.Student;
公共类JavaSpringClientTest{
公共静态void main(字符串[]args){
RestTemplate RestTemplate=新的RestTemplateBuilder().rootUri(“http://localhost:8080/v1/protected/students")
.basicAuthentication(“用户名”、“密码”).build();
ResponseEntity exchange=restemplate.exchange(“/?sort=id,asc”),HttpMethod.GET,null,
新的ParameteredTypeReference(){
});
System.out.println(exchange.getBody().getContent());
}
}
类用于分页和对API调用排序

package br.com.ironforge.springboottutorial.model;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;


public class PageableResponse<T> extends PageImpl<T> {

    private boolean last;
    private boolean first;
    private int totalPages;

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public PageableResponse(@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 PageableResponse(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public PageableResponse(List<T> content) {
        super(new ArrayList<T>());
    }

}
package br.com.ironferge.springboottotutorial.model;
导入java.util.ArrayList;
导入java.util.List;
导入org.springframework.data.domain.PageImpl;
导入org.springframework.data.domain.PageRequest;
导入org.springframework.data.domain.Pageable;
导入com.fasterxml.jackson.annotation.JsonCreator;
导入com.fasterxml.jackson.annotation.JsonProperty;
导入com.fasterxml.jackson.databind.JsonNode;
公共类PageableResponse扩展了PageImpl{
私有布尔最后;
私有布尔优先;
私人网页;
@JsonCreator(mode=JsonCreator.mode.PROPERTIES)
public PageableResponse(@JsonProperty(“content”)列表内容,@JsonProperty(“number”)整数,
@JsonProperty(“size”)int size、@JsonProperty(“totalElements”)Long totalElements、,
@JsonProperty(“pageable”)JsonNode pageable,@JsonProperty(“last”)布尔值last,
@JsonProperty(“totalPages”)int totalPages,
@JsonProperty(“排序”)JsonNode排序,
@JsonProperty(“first”)布尔值优先,@JsonProperty(“numberOfElements”)int numberOfElements){
super(内容、页面请求、数量、大小、元素总数);
}
public PageableResponse(列表内容、可分页、长总计){
超级(内容、可分页、总计);
}
public PageableResponse(列表内容){
super(新的ArrayList());
}
}

谢谢,但此解决方案与我发布的基本相同,它放弃了排序字段。这并没有回答我关于解析和保留排序内容的问题。
package br.com.ironforge.springboottutorial.javaclient;

import java.util.Arrays;
import java.util.List;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import br.com.ironforge.springboottutorial.model.PageableResponse;
import br.com.ironforge.springboottutorial.model.Student;

public class JavaSpringClientTest {

    public static void main(String[] args) {

        RestTemplate restTemplate = new RestTemplateBuilder().rootUri("http://localhost:8080/v1/protected/students")
                .basicAuthentication("username", "password").build();

        ResponseEntity<PageableResponse<Student>> exchange = restTemplate.exchange("/?sort=id,asc", HttpMethod.GET, null,
                new ParameterizedTypeReference<PageableResponse<Student>>() {
                });
        System.out.println(exchange.getBody().getContent());
    }
}
package br.com.ironforge.springboottutorial.model;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;


public class PageableResponse<T> extends PageImpl<T> {

    private boolean last;
    private boolean first;
    private int totalPages;

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public PageableResponse(@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 PageableResponse(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public PageableResponse(List<T> content) {
        super(new ArrayList<T>());
    }

}