外部API为我提供了一个JSON对象,如下所示:
{
"@date": "1407436242",
"@duration": "2411",
"Entry": {
"@position": "3",
"@playerName": "fred"
}
}
如您所见,除了一个嵌套对象之外,所有键都以@符号开头。我们正在使用GSON来解析JSON,并且我尝试尽可能简单地执行此操作,而无需手动将每个键转换为有效的Java字段名称。
我目前正在尝试使用此代码:
MyObject response = gson.fromJson(stringInput, MyObject.class);
并且除了TournamentEntry之外没有匹配任何字段。
我尝试添加了一个gson字段命名策略,但这似乎是一种全有或全无的方法,并且无法处理某些密钥具有" @"签字和一些不要。
我如何告诉GSON放弃" @"转换为Java字段名称时的符号,同时仍然处理没有@符号的嵌套对象?
答案 0 :(得分:3)
Gson提供SerializedName注释,允许使用那些时髦的json标识符。这会让你的课看起来像这样:
package com.example;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
public class Event {
@SerializedName("@date")
private Date date;
@SerializedName("@duration")
private long duration;
@SerializedName("Entry")
private Entry entry;
}
和
package com.example;
import com.google.gson.annotations.SerializedName;
public class Entry {
@SerializedName("@position")
private int position;
@SerializedName("@playerName")
private String playerName;
}
@SerializedName的优点在于它可以在每个字段的基础上工作,因此您只需要在需要时进行注释。
答案 1 :(得分:1)
您可以尝试首先使用GSON JsonParser
将JSON解析为JsonElement
,然后对其进行预处理,以删除以@开头的所有密钥并将其替换为实际密钥。之后,您可以使用修改后的gson.fromJson
而不是JSON字符串调用JsonElement
。
以下是如何执行此操作的示例。它检查元素是否是JSON对象,如果是,则替换以@开头的所有键。然后递归地将所有值放在同一个方法中(这样您也可以替换例如示例中的@position)。
public static void main(String... args) {
String json = "{\n"
+ " \"@date\": \"1407436242\",\n"
+ " \"@duration\": \"2411\",\n"
+ " \"Entry\": {\n"
+ " \"@position\": \"3\",\n"
+ " \"@playerName\": \"fred\"\n"
+ " }\n"
+ "}";
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(json);
// Modify the JsonElement, replacing any keys beginning with @
removeAtSymbolsInKeys(jsonElement);
MyObject myObject = new Gson().fromJson(jsonElement, MyObject.class);
System.out.println(myObject);
}
private static void removeAtSymbolsInKeys(JsonElement jsonElement) {
if (jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
Set<Entry<String, JsonElement>> entrySet = new HashSet<>(jsonObject.entrySet()); // Make a copy so we can modify JsonObject
for (Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
JsonElement value = entry.getValue();
if (key.startsWith("@")) {
String newKey = key.replaceFirst("@", "");
jsonObject.add(newKey, value);
jsonObject.remove(key);
}
// Replace the keys of any values that are objects
removeAtSymbolsInKeys(value);
}
}
}
请记住,如果您的JSON非常嵌套,递归方法将抛出StackOverflowError,但希望绝对不会这样。