Spring + Jackson +反序列化通用对象列表

时间:2014-02-13 00:56:40

标签: java json spring rest 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;
    }
}

当POST出现并查看我得到的对象时,有效负载列表包含LinkedHashMap对象而不是我的DTO类型的对象。

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

这是我正在尝试的JSON。

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

2 个答案:

答案 0 :(得分:2)

由于类型擦除,您的代码无效。 Jackson运行时不知道您正在尝试将有效负载编组到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等一起使用而不会出现故障。

答案 1 :(得分:0)

如果不要求使用杰克逊,那么您可能需要考虑使用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);