我有一个应用程序,它使用Jackson将一些数据存储在DynamoDB中,以便将我的复杂对象编组为JSON。
例如,我正在编组的对象可能如下所示:
private String aString;
private List<SomeObject> someObjectList;
SomeObject可能如下所示:
private int anInteger;
private SomeOtherObject;
和SomeOtherObject可能如下所示:
private long aLong;
private float aFloat;
这很好,对象被编组没有问题,并作为JSON字符串存储在DB中。
当从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'。
您可以使用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,而是使用内存中的事件序列作为中间步骤。
这个问题有一个很好的解决方案:
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 <T>。
也许有另一种解决方法,使用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();