Я получаю JSON
полезную нагрузку, которая представляет собой набор пар ключ-значение. Значение может быть либо строкой, либо числом. Я должен разобрать JSON
и сохранить пары ключ-значение в соответствующие varchar2
столбцы. Я должен сохранить входящий номер в точности так, как он был представлен во входных данных . Но для чисел, представленных как 1.1E4
, 0.00000000000003
и аналогичных, вместо этого я получаю 11000.0
, 3.0E-14
.
Можно ли отключить / запретить преобразование чисел, чтобы вместо него было только строковое представление?
Я использую FasterXML
Jackson
реализацию. Кстати, фактического документа нет в наличии - все источники, которые я нашел, указывают на http://wiki.fasterxml.com/JacksonHome, который сейчас недоступен. Я нашел два похожих вопроса здесь Джексон JSON преобразует целые числа в строки Отключить автоматическое преобразование числа в строку в Джексоне , но оба требуют исключения, когда встречаются номера, что не является моим случаем. Я пробовал предлагаемые решения, но не смог изменить их, чтобы они соответствовали моей задаче.
Также нет ответа в https://github.com/FasterXML/jackson-databind/issues/796
В настоящее время у меня нет спецификации для входной строки, кроме key-пары значений. Так что просто пример:
I может получить что-то вроде:
{"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}
Thisнамного лучше, но все равно различаются f=11000
вместо f=1.1E4
.