如何使用gson创建json,按键排序?

时间:2015-05-04 12:48:35

标签: java json gson

我需要创建常量json字符串或按键排序的json。常量json字符串是什么意思?请查看我创建的以下代码示例。

我的代码1:

public class GsonTest
{
    class DataObject {

        private int data1 = 100;
        private String data2 = "hello";

    }   


    public static void main(String[] args)
    {
        GsonTest obj=new GsonTest();
        DataObject obj2 = obj.new DataObject();
        Gson gson = new Gson();

        String json = gson.toJson(obj2);
        System.out.println(json);
    }
}

输出1:

{"data1":100,"data2":"hello"}

我的代码2:

public class GsonTest
{
    class DataObject {
        private String data2 = "hello";
        private int data1 = 100;


    }   


    public static void main(String[] args)
    {
        GsonTest obj=new GsonTest();
        DataObject obj2 = obj.new DataObject();
        Gson gson = new Gson();

        String json = gson.toJson(obj2);
        System.out.println(json);
    }
}

输出2:

{"data2":"hello","data1":100}

如果你看到,如果我在data1类中切换变量(data2& DataObject),我会得到不同的json。我的目标是获得相同的json,即使有人改变了类变量的位置。当有人添加新变量时,我会得到它,json会改变。但是当变量被移动时,json不应该改变。所以,我的目标是获得标准的json,可能是同一类的排序键顺序。如果存在嵌套的json,那么它应该在嵌套结构中进行排序。

代码运行时的预期输出

{"data1":100,"data2":"hello"}  //sorted on keys!! Here keys are data1 & data2

我明白,我需要改变String json = gson.toJson(obj2);行中的内容,但我该怎么做?

为什么我需要它们才能订购?

我需要对json字符串进行编码,然后将其传递给另一个函数。如果我更改键的顺序,即使值保持不变,编码值也会改变。我想避免这种情况。

3 个答案:

答案 0 :(得分:6)

首先,根据定义,json对象的键是无序,请参阅http://json.org/

如果您只想要一个带有有序键的json字符串,您可以尝试将json反序列化为有序映射,然后序列化映射以获取按键排序的json字符串。

GsonTest obj=new GsonTest();
DataObject obj2 = new DataObject();
Gson gson = new Gson();

String json = gson.toJson(obj2);
TreeMap<String, Object> map = gson.fromJson(json, TreeMap.class);
String sortedJson = gson.toJson(map);

答案 1 :(得分:0)

就像其他人提到的那样,JSON本身不应该对键进行排序。您也可以提出一个递归解决方案。我不会说我的解决方案非常有效,但是可以完成预期的工作。请看下面的代码。

private static JsonObject sortAndGet(JsonObject jsonObject) {
    List<String> keySet = jsonObject.keySet().stream().sorted().collect(Collectors.toList());
    JsonObject temp = new JsonObject();
    for (String key : keySet) {
        JsonElement ele = jsonObject.get(key);
        if (ele.isJsonObject()) {
            ele = sortAndGet(ele.getAsJsonObject());
            temp.add(key, ele);
        } else if (ele.isJsonArray()) {
            temp.add(key, ele.getAsJsonArray());
        } else
            temp.add(key, ele.getAsJsonPrimitive());
    }
    return temp;
}

输入:

{"c":"dhoni","a":"mahendra","b":"singh","d":{"c":"tendulkar","b":"ramesh","a":"sachin"}}

输出:

{"a":"mahendra","b":"singh","c":"dhoni","d":{"a":"sachin","b":"ramesh","c":"tendulkar"}}

答案 2 :(得分:-1)

也许为您的类解决的方法是包装一个TreeMap来维护键的排序顺序。为了方便起见,您可以添加getter和setter。在TreeMap中,您将获得有序的密钥。