У меня есть следующий файл json test.json
{
"type" : "object",
"id" : "123",
"title" : "Test",
"properties" : {
"_picnic" : {
"type" : "boolean"
....
Я могу получить значение ключа первого уровня, используя следующий код. Например. за type я получаю object
public static void main(String[] args){
String exampleRequest = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
exampleRequest = FileUtils.readFileToString(new File("src/main/resources/test.json"), StandardCharsets.UTF_8);
JsonNode jsonNode = objectMapper.readTree(exampleRequest);
String type = jsonNode.get("type").asText();
System.out.println(type);
} catch (IOException e) {
throw new RuntimeException(e);
}
// System.out.println(exampleRequest);
}
Однако я не получаю никакого ответа, когда пытаюсь получить значение для второго уровня. Например. если я сделаю
String type = jsonNode.get("_picnic").asText();
System.out.println(type);
OR the whole object e.g.
String type = jsonNode.get("properties").asText();
System.out.println(type);
Я пытался сделать properties._picnic или properties[0]_picnic, но безуспешно.




В документации к этому методу говорится (выделено мной):
Метод, возвращающий допустимое строковое представление значения контейнера, если узел является узлом значения (метод isValueNode() возвращает true), в противном случае пустая строка.
Согласно фрагменту текста json, которым вы поделились, и "properties", и "_picnic" являются объектами, а не значениями, поэтому вы получаете пустую строку. Кажется, вам нужно использовать метод get:
jsonNode.get("properties").get("_picnic").get("type").asText()
Спасибо за ответ, он получает значение типа, но почему он не дает мне блок для jsonNode.get("properties").get("_picnic").asText() или jsonNode.get("properties").asText()
Я уже объяснил это в своем ответе, но я обновлю, чтобы немного уточнить.
Итак, вы упомянули get, но не использовали его. Не могли бы вы добавить это и к ответу. Чтобы получить соответствующие объекты, используйте String type = String.valueOf(jsonNode.get("properties")); и String type = String.valueOf(jsonNode.get("properties").get("_picnic"));
Я показал пример получения в своем исходном ответе. String type = String.valueOf(jsonNode.get("properties")); будет неправильным, поскольку в опубликованном вами JSON "properties" является объектом.
Вы можете использовать рекурсию, чтобы упростить этот код. Просто вызовите getText с начальным узлом и переменным списком (массивом) путей. Он определит, нужно ли ему проверять объект или массив.
import java.io.*;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import com.fasterxml.jackson.databind.*;
public class NestedJson {
public static void main(String[] args) {
String exampleRequest = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
exampleRequest = FileUtils.readFileToString(new File("src/main/resources/test.json"),
StandardCharsets.UTF_8);
JsonNode jsonNode = objectMapper.readTree(exampleRequest);
System.out.println(getText(jsonNode, "type")); // object
System.out.println(getText(jsonNode, "properties", "_picnic", "type")); // boolean
System.out.println(getText(jsonNode, "stuff", "0", "foo")); // bar
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getText(JsonNode node, String... path) {
return getText(node, 0, path);
}
private static String getText(JsonNode node, int cursor, String[] path) {
if (node == null || path == null || path.length == 0)
return null;
if (cursor == path.length) {
return node != null ? node.asText() : null;
}
if (node.isObject()) {
return getText(node.get(path[cursor]), cursor + 1, path);
} else if (node.isArray()) {
return getText(node.get(Integer.parseInt(path[cursor])), cursor + 1, path);
}
return null;
}
}
Изменено test.json:
{
"type": "object",
"id": "123",
"title": "Test",
"properties": {
"_picnic": {
"type": "boolean"
}
},
"stuff": [
{
"foo": "bar"
}
]
}
Спасибо, проверю и отчитаюсь.
Я думаю, что в конечном итоге я ищу такое решение, но вместо того, чтобы передавать жестко закодированные аргументы, было бы неплохо использовать код, чтобы определить, является ли поступающий элемент массивом или объектом, и соответственно вызвать функцию.
Возможно, это может вам помочь stackoverflow.com/questions/14898768/…