如何反序列化以下JSON以跳过根元素并仅解析此JSON的内部部分。我想避免创建额外的第3课Root
,其中只包含MapWrapper
字段。
{
"root": {
"language": "en",
"map": {
"k1": {
"name": "n1",
},
"k2": {
"name": "n2",
}
}
}
}
所以我想只有这两个类:
class MapWrapper {
private String language;
private Map<String, MyMapEntry> map;
}
class MyMapEntry {
String name;
}
答案 0 :(得分:3)
考虑以下JSON:
{"authorization":{"username":"userabc", "password":"passabc"}}
没有根元素的此JSON的DTO
public class Authorization {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// Add a container for the root element
public static class Container {
public Authorization authorization;
}
}
使用以下方法从/转换为JSON(您可以将其保留在DTO或其他帮助类中)
public String toJson(Authorization authorization) {
Gson gson = new Gson();
Authorization.Container container = new Authorization.Container();
container.authorization = authorization;
return gson.toJson(container);
}
public Authorization fromJson(String json) {
Gson gson = new Gson();
Authorization.Container container = gson.fromJson(json, Authorization.Container.class);
return container.authorization;
}
答案 1 :(得分:2)
我的答案迟到了。
一旦我们解析了Json,容器总是成为JsonElement的JsonObject子类。因此,如果我们想跳过它,我们只需要将它转换为它的子类并抓住保存内部类的字段。
String response = ....;
Gson gson = new Gson();
JsonParser p = new JsonParser();
JsonElement jsonContainer = p.parse(response);
JsonElement jsonQuery = ((JsonObject) jsonContainer).get("query");
MyQuery query = gson.fromJson(jsonQuery, MyQuery.class);
注意:JsonObject和JSONObject是不同的类(使用com.google.Json导入)。
您可以更多地概括这个答案,这样您就不需要知道内部类的名称。您只需获取容器对象的唯一字段即可。但是,除了启动迭代器之外我没有办法做到这一点,没有我能看到的getValue(atIndex)方法,我认为启动迭代器可能不如简单地按名称查找字段(但可能是错)。
迭代器方法如下:
JsonElement jsonQuery = ((JsonObject) jsonContainer).entrySet().iterator()
.next().getValue();
答案 2 :(得分:0)
您可以将其反序列化为Map<String, MapWrapper>
。
答案 3 :(得分:0)
受Gustav Carlson的想法启发,我决定将其扩展为具体样本。这是一个junit测试,用于测试将此JSON解析为Map。
public static class MapWrapper {
private String language;
private Map<String, MyMapEntry> map;
}
public static class MyMapEntry {
String name;
}
@Test
public void testParsing() {
String json = "{\n" +
" \"root\": {\n" +
" \"language\": \"en\",\n" +
" \"map\": {\n" +
" \"k1\": {\n" +
" \"name\": \"n1\"\n" +
" },\n" +
" \"k2\": {\n" +
" \"name\": \"n2\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Type type = new TypeToken<Map<String, MapWrapper>>(){}.getType();
Map<String, MapWrapper> parsed = gson.fromJson(json, type);
MapWrapper mapWrapper = parsed.get("root");
Assert.assertEquals("en", mapWrapper.language);
Assert.assertEquals("n2", mapWrapper.map.get("k2").name);
}