【发布时间】:2019-11-06 04:43:37
【问题描述】:
我收到JSON 有效载荷,它是一组键值对。值可以是字符串或数字。我必须解析 JSON 并将键值对存储到适当的 varchar2 列中。我应该保存传入的号码与输入有效负载中显示的完全相同。
但是对于像1.1E4、0.00000000000003 和类似的数字,我会得到11000.0、3.0E-14。
这是一种禁用/防止数字转换为字符串表示的方法吗?
我使用FasterXML Jackson 实现。
顺便说一句,没有可用的实际文档——我发现的所有来源都指向http://wiki.fasterxml.com/JacksonHome,它现在已经关闭。
我在这里发现了两个类似的问题
Jackson JSON converts integers into strings
Disable the Number to String automatic conversion in jackson
但是遇到号码时两者都需要例外,这不是我的情况。我尝试了建议的解决方案,但未能成功修改它们以适应我的任务。
也没有答案 https://github.com/FasterXML/jackson-databind/issues/796
现在除了键值对之外,我没有输入字符串的规范。所以只是一个例子:
我可能收到如下信息:
{"a":"text", "b":"35", "c":{"d":"another"}, "e":["array",35], "f":1.1E4, "g":0.00000000000003}
我想要字符串对
"a" -> "text", "b" -> "35", "c" -> "{\"d\":\"another\"}", "e" -> "[\"array\",35]", "f" -> "1.1E4"
最简单的转换方式是:
public void test() throws IOException {
Map map = new ObjectMapper().readValue(
"{\"a\":\"text\", \"b\":\"35\", \"c\":{\"d\":\"another\"}, \"e\":[\"array\",35], \"f\":1.1E4, \"g\":0.00000000000003}"
, Map.class);
System.out.println(map);
}
结果:
{a=text, b=35, c={d=another}, e=[array, 35], f=11000.0, g=3.0E-14}
更准确的方法:
public class JsonUtil2 {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static Map<String, String> parse(String json) throws IOException {
ObjectNode objectNode = (ObjectNode) OBJECT_MAPPER.readTree(json);
Map<String, String> result = new HashMap<>(objectNode.size());
objectNode.fields().forEachRemaining(entry -> result.put(entry.getKey(), toJson(entry.getValue())));
return result;
}
private static String toJson(JsonNode jsonNode) {
if (jsonNode.isNumber()) {
if (jsonNode instanceof DoubleNode || jsonNode instanceof FloatNode) {
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
dfs.setMinusSign('-');
DecimalFormat df = new DecimalFormat("#.#", dfs);
df.setMaximumFractionDigits(32);
df.setMaximumIntegerDigits(32);
return df.format(jsonNode.doubleValue());
} else {
return jsonNode.asText();
}
} else if (jsonNode.isValueNode()) {
return jsonNode.asText();
} else {
try {
return OBJECT_MAPPER.writeValueAsString(jsonNode);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
}
导致:
{a=text, b=35, c={"d":"another"}, e=["array",35], f=11000, g=0.00000000000003}
这要好得多,但在 f=11000 而不是 f=1.1E4 中仍然存在差异。
【问题讨论】:
-
请展示您的 JSON 字符串以及如何解析它!
-
您可以使用
BigInteger或BigDecimal。 -
@MC Emperor,我需要将解析的键值对作为字符串存储在数据库中。我怎么能使用 BigDecimal 呢?
标签: java json jackson json-deserialization scientific-notation