如何从嵌套的JSON中获取数据?
How to get data from nested JSON?
这是我的代码:
public class Parser {
private static final String PATH = "try.json";
public static void main(String[] args) throws IOException, ParseException {
String req = FileUtils.readFileToString(new File(PATH), StandardCharsets.UTF_8);
Bean data = new Gson().fromJson(req, Bean.class);
public class Bean{
private List<Data> data;
public List<Data> getData() {
return data;
}
public class Data {
private List<String> urls;
private String name;
private String type;
private String picture;
public List<String> getUrls() {
return urls;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getPicture() {
return picture;
}
}
这是假人-JSON:
{
"data": [
{
"urls": [
"https://google.com",
"https://googl.com"
],
"name": "Google",
"type": "corp",
"picture": "https://google.img"
},
{
"urls": [
"https://yandex.ru"
],
"name": "Yandex",
"type": "corp",
"picture": "https://yandex.jpg"
}
]
}
这里的主要任务是从 json 创建带有“name”字段和“urls”ArrayList 的单个对象,然后我将它们添加到另一个列表中并通过索引获取信息。
但我就是不明白,我该怎么做。例如,对于第一个对象的响应可能应该如下所示:
Google
"https://google.com",
"https://googl.com"
好吧,如果您不强制使用 GSON,您可以使用 Jackson。
通过使用@JsonProperty
注解,你可以获得嵌套的字段,如果需要,你还可以添加一些带有@JsonAlias
的别名。
这是一个简短的例子:
import com.fasterxml.jackson.annotation.JsonProperty;
public class Data {
private List<String> urls;
private String name;
private String type;
private String picture;
public List<String> getUrls() {
return urls;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getPicture() {
return picture;
}
}
@JsonProperty("ParentObject") //Here it looks like the parent object is an element of the array Data, so i would treat you Json object as a list of objects and iterate over each.
private void getFieldNestedValues(Map<String, String> field) {
urls = field.get("nestedField1"); //nestedField1 would be urls in your case
name = field.get("nestedField2"); // nestedField2 could be the name for instance
}
我很确定您可以对 Gson 做同样的事情,希望这个示例能让您了解如何让它发挥作用。
编辑:忘记提及我会使用 Jackson 库中的 ObjectMapper
来解析和构建对象:
JsonNode rootNode = objectMapperProvider.buildSureObjectMapper().readTree(jsonBody);
YourObject yourObject= objectMapperProvider.buildSureObjectMapper().readValue(rootNode.toString(), YourObject.class);
例如使用自定义 ObjectMapper:
public ObjectMapper buildSureObjectMapper() {
return new ObjectMapper()
.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule())
.registerModule(new GuavaModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setSerializationInclusion(NON_ABSENT);
}
如果我没理解错的话,你想要一个循环
Bean data = new Gson().fromJson(req, Bean.class);
for (Data d : data.getData()) {
System.out.println(d.getName());
for (String u : d.getUrls()) {
System.out.println(u);
}
}
否则,你已经可以通过索引访问东西了
Data first = data.getData().get(0);
System.out.println(first.getName()); // google
这是我的代码:
public class Parser {
private static final String PATH = "try.json";
public static void main(String[] args) throws IOException, ParseException {
String req = FileUtils.readFileToString(new File(PATH), StandardCharsets.UTF_8);
Bean data = new Gson().fromJson(req, Bean.class);
public class Bean{
private List<Data> data;
public List<Data> getData() {
return data;
}
public class Data {
private List<String> urls;
private String name;
private String type;
private String picture;
public List<String> getUrls() {
return urls;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getPicture() {
return picture;
}
}
这是假人-JSON:
{
"data": [
{
"urls": [
"https://google.com",
"https://googl.com"
],
"name": "Google",
"type": "corp",
"picture": "https://google.img"
},
{
"urls": [
"https://yandex.ru"
],
"name": "Yandex",
"type": "corp",
"picture": "https://yandex.jpg"
}
]
}
这里的主要任务是从 json 创建带有“name”字段和“urls”ArrayList 的单个对象,然后我将它们添加到另一个列表中并通过索引获取信息。 但我就是不明白,我该怎么做。例如,对于第一个对象的响应可能应该如下所示:
Google
"https://google.com",
"https://googl.com"
好吧,如果您不强制使用 GSON,您可以使用 Jackson。
通过使用@JsonProperty
注解,你可以获得嵌套的字段,如果需要,你还可以添加一些带有@JsonAlias
的别名。
这是一个简短的例子:
import com.fasterxml.jackson.annotation.JsonProperty;
public class Data {
private List<String> urls;
private String name;
private String type;
private String picture;
public List<String> getUrls() {
return urls;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getPicture() {
return picture;
}
}
@JsonProperty("ParentObject") //Here it looks like the parent object is an element of the array Data, so i would treat you Json object as a list of objects and iterate over each.
private void getFieldNestedValues(Map<String, String> field) {
urls = field.get("nestedField1"); //nestedField1 would be urls in your case
name = field.get("nestedField2"); // nestedField2 could be the name for instance
}
我很确定您可以对 Gson 做同样的事情,希望这个示例能让您了解如何让它发挥作用。
编辑:忘记提及我会使用 Jackson 库中的 ObjectMapper
来解析和构建对象:
JsonNode rootNode = objectMapperProvider.buildSureObjectMapper().readTree(jsonBody);
YourObject yourObject= objectMapperProvider.buildSureObjectMapper().readValue(rootNode.toString(), YourObject.class);
例如使用自定义 ObjectMapper:
public ObjectMapper buildSureObjectMapper() {
return new ObjectMapper()
.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule())
.registerModule(new GuavaModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setSerializationInclusion(NON_ABSENT);
}
如果我没理解错的话,你想要一个循环
Bean data = new Gson().fromJson(req, Bean.class);
for (Data d : data.getData()) {
System.out.println(d.getName());
for (String u : d.getUrls()) {
System.out.println(u);
}
}
否则,你已经可以通过索引访问东西了
Data first = data.getData().get(0);
System.out.println(first.getName()); // google