我有以下控制器:
@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"
}
]
}
答案 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);