有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring+Jackson+反序列化泛型对象列表

我有以下控制器:

@RequestMapping(value = "/test/inst/", method = RequestMethod.POST)
public @ResponseBody ResponseDTO<InstDTO> 
        testPostREST(@RequestBody RequestDTO<InstDTO> instDTO) {

    RequestDTO<InstDTO> dto = new RequestDTO<InstDTO>();

    ResponseDTO<InstDTO> responseDto = new ResponseDTO<InstDTO>();
    responseDto.setPayload(instDTO.getPayload());
    return responseDto; 
}

使用以下请求对象:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class RequestDTO<T> {

    private List<T> payload;

    public RequestDTO() {
        System.out.println("constructor");
    }

    public RequestDTO(List<T> payload) {
        this.payload = payload;
    }

    public List<T> getPayload() {
        return payload;
    }

    public void setPayload(List<T> payload) {
        this.payload = payload;
    }
}

当帖子发完,我查看得到的对象时,有效负载列表中有LinkedHashMap对象,而不是我的DTO类型的对象

如何让spring+jackson将JSON转换为DTO对象。请记住,我计划对其他对象列表重用wrapper ResponseDTO,这就是我使用通用列表(list)的原因

这是我正在尝试的JSON

{
  "payload": [
    {
      "d": "Test 0",
      "id": "abcde",
      "c": "Test 0"
    },
    {
      "d": "Test 1",
      "id": "123",
      "c": "Test 1"
    }
  ]
}

共 (2) 个答案

  1. # 1 楼答案

    由于类型擦除,您的代码无法工作。Jackson runtime不知道您正在尝试将有效负载封送到InstitutionDTO对象中(因为此信息在编译时已被删除)。当Jackson查看有效负载时,它会在连线上看到有效的JSON对象,在Java端看到一个List<Object>。它别无选择,只能将有效负载映射到Map实现,在您的例子中,它似乎是LinkedHashMap

    你可以通过以下方式实现你想要的目标:

    class RequestDTO<T> {}
    class ResponseDTO<T> {}
    class InstitutionDTO {}
    class InstitutionRequestDTO extends RequestDTO<InstitutionDTO>
    class InstitutionResponseDTO extends ResponseDTO<InstitutionDTO>
    
    @RequestMapping(value = "/test/institution/", method = RequestMethod.POST)
    public @ResponseBody InstitutionResponseDTO
        testPostREST(@RequestBody InstitutionRequestDTO institutionDTO) { }
    

    免责声明:我自己还没有尝试过这段代码,但我的大多数应用程序都有类似的代码,它可以与Jackson、Castor、Atom等一起使用,没有任何问题

  2. # 2 楼答案

    如果使用杰克逊不是要求,那么您可能需要考虑使用GSON代替。

    只需向Gson传递一个json字符串和要反序列化的类,就可以告诉Gson如何反序列化json。这很简单。下面我举了一个例子,我必须反序列化rest api的响应

    entity = response.getEntity();
    jsonResponse = EntityUtils.toString(entity);
    JsonNode root = mapper.readTree(jsonResponse).get("result");
    returnedProduct = gson.fromJson(root.toString(),Product.class);