Jackson反序列化映射数组,使用javax约束验证TreeMap



我为反序列化映射数组编写了自定义JsonDeserializer:

"fieldNr2": [
{
"3.0": 3.1
},
{
"2.0": 2.1
},
{
"4.0": 4.1
},
{
"5.0": 5.1
},
{
"1.0": 1.1
}
]

到带有javax验证的TreeMap:

TreeMap<@Positive BigDecimal, @NotNull @Positive BigDecimal>

问题是,我不知道如何在ObjectCodec.readValue((方法中定义映射数组(为键和值指定类(。我尝试过使用TypeReference,但没有成功。

我的代码在哪里:

class TreeMapDeserializer extends JsonDeserializer<TreeMap<BigDecimal, BigDecimal>> {
@Override
public TreeMap<BigDecimal, BigDecimal> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
TreeMap<BigDecimal, BigDecimal>[] input = oc.readValue(jsonParser, TreeMap[].class);
TreeMap<BigDecimal, BigDecimal> output = new TreeMap<>();
for (TreeMap map : input) {
Map.Entry<BigDecimal, BigDecimal> mapEntry = (Map.Entry<BigDecimal, BigDecimal>) map.entrySet().stream().findFirst().get();
BigDecimal key = mapEntry.getKey();
BigDecimal value = mapEntry.getValue();
output.put(key, value);
}
return output;
}

此外,当我注释掉javax约束验证时。应用程序运行时没有问题,但当我打开它时,Jackson尝试将String解析为BigDecimal(?(失败,或者无法将Double解析为BigDecimal(吗(失败。

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: java.lang.String cannot be cast to java.math.BigDecimal; nested exception is com.fasterxml.jackson.databind.JsonMappingException: java.lang.String cannot be cast to java.math.BigDecimal (through reference chain:

您可以这样做。您的键,值的类型为String和Double。

public static Map<String, String> gsonMap2Map(JsonParser parser) throws IOException {
ObjectCodec codec = parser.getCodec();
TreeNode node = codec.readTree(parser);
TreeMap<String, Double> ret = new TreeMap<String, Double>();
if (node.isObject()) {
for (Iterator<String> iter = node.fieldNames(); iter.hasNext();) {
String fieldName = iter.next();
TreeNode field = node.get(fieldName);
if (field != null) {
ret.put(fieldName, field.toDouble());
} else {
ret.put(fieldName, "null");
}
}
}
return ret;
}

解决方案:

public TreeMap<BigDecimal, BigDecimal> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
List<Map.Entry<BigDecimal, BigDecimal>> input = oc.readValue(jsonParser, new TypeReference<List<Map.Entry<BigDecimal, BigDecimal>>>(){});
Map<BigDecimal, BigDecimal> intermediateMap = input.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return new TreeMap<>(intermediateMap);
}

public Map<SecretClass, BigDecimal> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
List<Map.Entry<SecretClass, BigDecimal>> input = oc.readValue(jsonParser, new TypeReference<List<Map.Entry<SecretClass, BigDecimal>>>(){});
return input.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

最新更新