Java-如何用嵌套对象和列表反序列化JSON数组?
如何反序列化包含其他对象中对象列表的JSON字符串?我找到了简单反序列化的解释,但我不能从中推断出太多,因为它们都有点偏离。例如(POJOs ommited),例如Java-如何用嵌套对象和列表反序列化JSON数组?,java,json,nested,deserialization,Java,Json,Nested,Deserialization,如何反序列化包含其他对象中对象列表的JSON字符串?我找到了简单反序列化的解释,但我不能从中推断出太多,因为它们都有点偏离。例如(POJOs ommited),例如 String json=“[{ “id”:33147, “名称”:“再融资”, “照片”:[{ “名称”:“347.png”, “url”:“/loans/568/photos/092” } ], “用户名”:“zach1985” } , { “id”:7693, “名称”:“材料”, “照片”:[{ “名称”:“newpic1.p
String json=“[{
“id”:33147,
“名称”:“再融资”,
“照片”:[{
“名称”:“347.png”,
“url”:“/loans/568/photos/092”
} ],
“用户名”:“zach1985”
} , {
“id”:7693,
“名称”:“材料”,
“照片”:[{
“名称”:“newpic1.png”,
“url”:“/loans/123446/photos/890”
} ],
“用户名”:“sengaia”
} ]";
ArrayList ads=新的ArrayList;
反序列化(json、ads);
System.out.println(ads.get(1.getName());
System.out.println(ads.get(0.getPhotos().get(0.getName());
输出将是“Stuff”和“347”。那么反序列化()方法需要如何实现呢?正如我在对问题的评论中所指出的,这里的测试演示了如何实现这一点:
public class JSONTest {
public static class FullyTypedThing {
public int id;
public String name;
public List<Photos> photos = Lists.newArrayList();
public String username;
public static class Photos {
public String name;
public String url;
}
}
private static final String json = "[ { \"id\" : 33147, \"name\" : \"Refinancing\", \"photos\" : [ {"
+ "\"name\" : \"347.png\", \"url\" : \"/loans/568/photos/092\" } ],"
+ "\"username\" : \"zach1985\"} , { \"id\" : 7693, \"name\" : \"Stuff\","
+ "\"photos\" : [ { \"name\" : \"newpic1.png\", \"url\" : \"/loans/123446/photos/890\" } ],"
+ "\"username\" : \"sengaia\" } ]";
@Test
public void roundtrip() throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<FullyTypedThing> res = Lists.newArrayList(
mapper.readValue(json, FullyTypedThing[].class));
assertEquals(2, res.size());
assertEquals(33147, res.get(0).id);
assertEquals("Refinancing", res.get(0).name);
assertEquals("347.png", res.get(0).photos.get(0).name);
assertEquals("/loans/568/photos/092", res.get(0).photos.get(0).url);
assertEquals(7693, res.get(1).id);
assertEquals("Stuff", res.get(1).name);
assertEquals("newpic1.png", res.get(1).photos.get(0).name);
assertEquals("/loans/123446/photos/890", res.get(1).photos.get(0).url);
assertEquals("[{\"id\":33147,\"name\":\"Refinancing\",\"photos\":"
+ "[{\"name\":\"347.png\",\"url\":\"/loans/568/photos/092\"}],"
+ "\"username\":\"zach1985\"},{\"id\":7693,\"name\":\"Stuff\","
+ "\"photos\":[{\"name\":\"newpic1.png\",\"url\":\"/loans/123446/photos/890\"}],"
+ "\"username\":\"sengaia\"}]", mapper.writeValueAsString(res));
}
}
公共类JSONTest{
公共静态类FullyTypedThing{
公共int id;
公共字符串名称;
public List photos=Lists.newArrayList();
公共字符串用户名;
公开静态课堂照片{
公共字符串名称;
公共字符串url;
}
}
私有静态最终字符串json=“[{\'id\':33147,\'name\':\'refining\',\'photos\':[{”
+“\“name\”:\“347.png\”,\“url\”:\“/loans/568/photos/092\”}],”
+“\'username\':\'zach1985\'},{\'id\':7693,\'name\':\'Stuff\',”
+“\'photos\\:[{\'name\':\'newpic1.png\',\'url\':\”/loans/123446/photos/890\“}],”
+“\”用户名\“:\”森盖亚\“}]”;
@试验
public void往返()引发IOException{
ObjectMapper mapper=新的ObjectMapper();
List res=Lists.newArrayList(
readValue(json,FullyTypedThing[].class));
资产质量(2,res.size());
assertEquals(33147,res.get(0.id));
资产质量(“再融资”,res.get(0).名称);
assertEquals(“347.png”,res.get(0.photos.get(0.name));
assertEquals(“/loans/568/photos/092”,res.get(0.photos.get(0.url));
assertEquals(7693,res.get(1.id));
assertEquals(“Stuff”,res.get(1).名称);
assertEquals(“newpic1.png”,res.get(1.photos.get(0.name));
assertEquals(“/loans/123446/photos/890”,res.get(1.photos.get(0.url));
资产质量(“[{\“id\”:33147,\“名称\”:“再融资\”,“照片\”:”
+“[{\'name\':\'347.png\',\'url\':\”/loans/568/photos/092\“}],”
+“\'username\':\'zach1985\'},{\'id\':7693,\'name\':\'Stuff\',”
+“\'photos\\:[{\'name\':\'newpic1.png\',\'url\':\”/loans/123446/photos/890\“}],”
+“\“username\:\“sengaia\”}]”,mapper.writeValueAsString(res));
}
}
您无法将其反序列化为arraylist。arraylist只保存一个没有值的键。我建议您使用HashMap。编辑:哎呀,我没看到它是一个JSON数组。@Martacus它是一个JSON数组。问:如何反序列化包含其他对象中对象列表的JSON字符串?有很多不同的方法。如果您打算更广泛地使用Java中的JSON,我建议您熟悉Jackson:正如其他人所指出的,学习类似Jackson的JSON框架。然后使用ObjectMapper
将JSON转换为对象@Oleg指出您可以使用:newObjectMapper().readValue(data,FullyTypedThing.class)
-如果要读取数组,只需将该类的数组传递给相同的方法,如:newObjectMapper().readValue(data,FullyTypedThing[].class
您可能还需要根据您的需求配置ObjectMapper
(Jackson有一些选项)。但我认为只要开始,然后尝试调整ObjectMapper
,如果需要,可以调用其#configure(…)
和setVisibility(…)
方法“ObjectMapper”是指“Jackson库”:(2)在您的示例中,使用mapper.readValue(…,FullyTypedThing.class)
。这没关系。但Jackson还允许您访问JSON实体,而不必定义相应的Java类(如果需要)。是的,我使用Jackson,这实际上是标准。关于第二点,我看不到。我知道我可以做到,那又怎样?如果可以,为什么我需要非类型化数据和大量解析代码是否正确键入并在一行中完成,透明、清晰且类型安全?定义holder类(如本测试中的一个)需要5分钟的时间,即使对于更复杂的数据结构也是如此。是的,在处理异构集合时,可能需要原始访问,但我会质疑数据异构背后的原因。更多通常这是糟糕的设计。
public class JSONTest {
public static class FullyTypedThing {
public int id;
public String name;
public List<Photos> photos = Lists.newArrayList();
public String username;
public static class Photos {
public String name;
public String url;
}
}
private static final String json = "[ { \"id\" : 33147, \"name\" : \"Refinancing\", \"photos\" : [ {"
+ "\"name\" : \"347.png\", \"url\" : \"/loans/568/photos/092\" } ],"
+ "\"username\" : \"zach1985\"} , { \"id\" : 7693, \"name\" : \"Stuff\","
+ "\"photos\" : [ { \"name\" : \"newpic1.png\", \"url\" : \"/loans/123446/photos/890\" } ],"
+ "\"username\" : \"sengaia\" } ]";
@Test
public void roundtrip() throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<FullyTypedThing> res = Lists.newArrayList(
mapper.readValue(json, FullyTypedThing[].class));
assertEquals(2, res.size());
assertEquals(33147, res.get(0).id);
assertEquals("Refinancing", res.get(0).name);
assertEquals("347.png", res.get(0).photos.get(0).name);
assertEquals("/loans/568/photos/092", res.get(0).photos.get(0).url);
assertEquals(7693, res.get(1).id);
assertEquals("Stuff", res.get(1).name);
assertEquals("newpic1.png", res.get(1).photos.get(0).name);
assertEquals("/loans/123446/photos/890", res.get(1).photos.get(0).url);
assertEquals("[{\"id\":33147,\"name\":\"Refinancing\",\"photos\":"
+ "[{\"name\":\"347.png\",\"url\":\"/loans/568/photos/092\"}],"
+ "\"username\":\"zach1985\"},{\"id\":7693,\"name\":\"Stuff\","
+ "\"photos\":[{\"name\":\"newpic1.png\",\"url\":\"/loans/123446/photos/890\"}],"
+ "\"username\":\"sengaia\"}]", mapper.writeValueAsString(res));
}
}