java - 以数字作为属性名称的 Json 映射
问题描述
我以以下 json 为例:
{
"success": true,
"data": {
"1": {
"amount": "1"
},
"2": {
"amount": "98"
}
}
}
不幸的是,我无法控制传入的 JSON 结构。我一直在尝试找到一种使用 JSONProperties 将这些映射到 DTO 的方法,但是我不能使用数字声明属性。
我也尝试过使用 JSONObject 迭代认为 JSON,但我似乎无法让它通过所有子节点,只是顶层。
JSONObject payload = new JSONObject(jsonString);
JSONObject newPayload = payload;
Iterator<String> keys = payload.keys();
while (keys.hasNext()) {
String key = keys.next();
if (StringUtils.isNumber(key)) {
newPayload.put("element" + key, payload.get(key));
newPayload.remove(key);
}
}
有没有人遇到过类似的情况并找到了解决方案。
所有这一切最终将 JSON 转换为 XML...继承了这个平台,没有时间重构大声笑,不是我的选择。
解决方案
有许多解决方案,但假设您只需要反序列化这种病态结构,这就是我的处理方式(Groovy 风格的紧凑性):
class ResponseData {
Map<String, Long> amounts = new HashMap<>() // or different key type
static class WrappedAmount {
String amount
Long getAmountAsLong() {
return Long.valueOf(amount)
}
}
@JsonAnySetter // this is the magic step
void appendAmount(String key, WrappedAmount amount) {
amounts.put(key, amount.getAmountAsLong())
}
}
class Response {
boolean success // REST endpoints should use status codes, not properties
ResponseData data
}
这会将您的响应反序列化为可管理的数据结构。如果按照您的建议,这些键是索引,并且将被删除并替换为 XML 标记的排序之类的东西,您可能希望替换HashMap
为,TreeMap
以便您可以迭代它以生成输出。
推荐阅读
- c# - 使用 ASP.net MVC 上的现有表
- mysql - 无法匹配 freeradius 中的 mysql 字符串响应
- extjs - 带触发器的文本区域 - 如何将触发器添加到选项卡
- javascript - 奇怪的 Javascript 行为,不计算明显的结果
- kubernetes - kubectl 通过负载均衡器
- python - 得到分散 c=? 颜色图和标准化
- xquery - xdmp:word-convert() 与 MarkLogic 中的 DOCX
- sql - 条件 UNION 中的错误
- python-3.x - 尝试用我自己的数据而不是 cifar10 生成 Keras 模型
- php - 尊重验证可选密钥