将LinkedHashMap转换为复杂对象

时间:2013-03-15 11:03:13

标签: java casting jackson linkedhashmap

我有一个应用程序,它使用Jackson将一些数据存储在DynamoDB中,以便将我的复杂对象编组为JSON。

例如,我正在编组的对象可能如下所示:

private String aString;
private List<SomeObject> someObjectList;

SomeObject可能如下所示:

private int anInteger;
private SomeOtherObject;

和SomeOtherObject可能如下所示:

private long aLong;
private float aFloat; 

这很好,对象被编组没问题,并作为JSON字符串存储在数据库中。

当从DynamoDB检索数据时,Jackson会自动检索JSON并将其转换回来...除了'someObjectList'作为List<LinkedHashMap>而不是List<SomeObject>返回!这是杰克逊的标准行为,这不是错误。

所以现在这会导致问题。我的代码库认为它处理的是List<SomeObject>,但实际情况是它处理List<LinkedHashMap>!我的问题是如何让我的LinkedHashMap回到'SomeObject'。显然这是一个手动过程,但我的意思是我甚至无法提取值。

如果我这样做:

for (LinkedHashMap lhm : someObjectList) {
    // Convert the values back
}

我收到编译错误,告诉我someObjectList的类型为'SomeObject'而不是LinkedHashMap。

如果我这样做:

for (SomeObject lhm : someObjectList) {
    // Convert the values back
}

我收到运行时错误,告诉我LinkedHashMap无法转换为'SomeObject'。

3 个答案:

答案 0 :(得分:104)

您可以使用ObjectMapper.convertValue(),按值或甚至整个列表使用值。但您需要知道要转换为的类型:

POJO pojo = mapper.convertValue(singleObject, POJO.class);
// or:
List<POJO> pojos = mapper.convertValue(listOfObjects, new TypeReference<List<POJO>>() { });

这在功能上与您一样:

byte[] json = mapper.writeValueAsBytes(singleObject);
POJO pojo = mapper.readValue(json, POJO.class);

但避免将数据实际序列化为JSON,而是使用内存中的事件序列作为中间步骤。

答案 1 :(得分:0)

有一个很好的解决方案:

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper objectMapper = new ObjectMapper();

***DTO premierDriverInfoDTO = objectMapper.convertValue(jsonString, ***DTO.class); 

Map<String, String> map = objectMapper.convertValue(jsonString, Map.class);

为什么会发生此问题?我想您在将字符串转换为对象时没有指定特定类型,该对象是具有通用类型的类,例如User

也许还有另一种解决方法,使用Gson代替ObjectMapper。 (或在此处查看Deserializing Generic Types with GSON

Gson gson = new GsonBuilder().create();

Type type = new TypeToken<BaseResponseDTO<List<PaymentSummaryDTO>>>(){}.getType();

BaseResponseDTO<List<PaymentSummaryDTO>> results = gson.fromJson(jsonString, type);

BigDecimal revenue = results.getResult().get(0).getRevenue();

答案 2 :(得分:0)

我有一个类似的问题,我们有包含值列表的GenericResponse对象

 ResponseEntity<ResponseDTO> responseEntity = restTemplate.exchange(
                redisMatchedDriverUrl,
                HttpMethod.POST,
                requestEntity,
                ResponseDTO.class
        );

objectMapper的使用有助于将LinkedHashMap转换为相应的DTO对象

 ObjectMapper mapper = new ObjectMapper();

 List<DriverLocationDTO> driverlocationsList = mapper.convertValue(responseDTO.getData(), new TypeReference<List<DriverLocationDTO>>() { });