使用GSON,如何JSON转换成Java时,一些键有特殊字符
外部API给了我一个JSON对象,如下所示:使用GSON,如何JSON转换成Java时,一些键有特殊字符
{
"@date": "1407436242",
"@duration": "2411",
"Entry": {
"@position": "3",
"@playerName": "fred"
}
}
正如你可以看到,所有的键开始的@符号,除了为一个,这是一个嵌套的对象。我们正在使用GSON来解析JSON,并且我正在尽可能简单地执行此操作,而无需手动将每个密钥转换为有效的Java字段名称。
我目前使用此代码尝试:
MyObject response = gson.fromJson(stringInput, MyObject.class);
这种匹配除了TournamentEntry没有字段。
我试过添加了一个gson字段命名策略,但是这似乎是一个全有或全无的方法,并且无法处理某些键具有“@”符号,而有些键不符合。
如何让GSON在转换为Java字段名称时删除“@”符号,同时仍处理没有@符号的嵌套对象?
您可以尝试首先使用GSON的JsonParser
将您的JSON解析为JsonElement
,然后对其进行预处理,以删除以@开头的任何密钥并将其替换为实际密钥。之后,您可以拨打gson.fromJson
修改JsonElement
而不是JSON字符串。
下面是如何做到这一点的一个例子。它检查元素是否是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);
}
}
}
请记住,递归方法将抛出的StackOverflowError如果你的JSON是极其嵌套的,但这应该有希望永远如此。
你知道,只写一个接受Map的构造函数会更简单,更直接。 – 2014-09-02 19:19:24
@HotLicks也许,但原始问题要求解决方案“无需手动将每个键转换为有效的Java字段名称”。 – andersschuller 2014-09-02 19:44:37
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伟大的事情是,它在每场的基础上,所以你只需要在需要时进行注释。
您可以尝试使用jsonString.replaceAll(“\\ @”,“”)来移除所有的@ – SparkOn 2014-08-30 13:47:50
您可以使用十几种不同的JSON工具包中的任何一种来生成相应的嵌套Map对象。 – 2014-08-30 13:58:00
@SparkOn这就是我正在使用的当前方法......但某些值域中可能有@符号......所以这并不理想。 – 2014-08-30 14:27:09