似乎像Gson.toJson(Object object)生成JSON代码,其中包含对象的随机扩展字段。有办法以某种方式修复字段顺序吗?
public class Foo {
public String bar;
public String baz;
public Foo( String bar, String baz ) {
this.bar = bar;
this.baz = baz;
}
}
Gson gson = new Gson();
String jsonRequest = gson.toJson(new Foo("bar","baz"));
// jsonRequest now can be { "bar":"bar", "baz":"baz" } (which is correct)
// and can be { "baz":"baz", "bar":"bar" } (which is a wrong sequence)
感谢。
答案 0 :(得分:25)
您需要创建自定义JSON序列化程序。
E.g。
public class FooJsonSerializer implements JsonSerializer<Foo> {
@Override
public JsonElement serialize(Foo foo, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
object.add("bar", context.serialize(foo.getBar());
object.add("baz", context.serialize(foo.getBaz());
// ...
return object;
}
}
并按如下方式使用:
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, new FooJsonSerializer()).create();
String json = gson.toJson(foo);
// ...
这样可以保持序列化程序中指定的顺序。
答案 1 :(得分:19)
如果GSON不支持字段顺序的定义,则可以使用其他库。例如,Jackson允许使用@JsonPropertyOrder来定义它。必须指定一个自己的自定义序列化器对我来说似乎是非常多的工作。
是的,我同意根据JSON规范,应用程序不应该期望字段的特定排序。
答案 2 :(得分:2)
这是我的解决方案,用于循环给定目录中的json文本文件,并使用排序版本在其顶部写入:
private void standardizeFormat(File dir) throws IOException {
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File child : directoryListing) {
String path = child.getPath();
JsonReader jsonReader = new JsonReader(new FileReader(path));
Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapter(LinkedTreeMap.class, new SortedJsonSerializer()).create();
Object data = gson.fromJson(jsonReader, Object.class);
JsonWriter jsonWriter = new JsonWriter(new FileWriter(path));
jsonWriter.setIndent(" ");
gson.toJson(data, Object.class, jsonWriter);
jsonWriter.close();
}
}
}
private class SortedJsonSerializer implements JsonSerializer<LinkedTreeMap> {
@Override
public JsonElement serialize(LinkedTreeMap foo, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
TreeSet sorted = Sets.newTreeSet(foo.keySet());
for (Object key : sorted) {
object.add((String) key, context.serialize(foo.get(key)));
}
return object;
}
}
它非常hacky,因为它取决于当Type只是Object时Gson使用LinkedTreeMap这一事实。这是一个可能无法保证的实现细节。无论如何,这对我的短暂目的来说已经足够了......
答案 3 :(得分:0)
实际上,Gson.toJson(Object object)不会以随机顺序生成字段。产生的json的顺序取决于字段名称的字面顺序。
我遇到了同样的问题,并且通过类中属性名称的字面顺序解决了。