如何使用Gson创建嵌套的JSON对象?

时间:2015-08-06 10:27:19

标签: java json gson

我编写了一个程序来进行一些概率计算,并以数组的形式给出结果。我想将这些结果转换为JSON格式,但我遇到了问题。

我希望我的json对象看起来像这样:

{
    "totalSuggestions": 6,
    "routes": {
        "rank_2": {
            "Source": "ABC",
            "Weight": "0.719010390625",
            "Destination": "XYZ"
        },
        "rank_1": {
            "Source": "XYZ",
            "Weight": "0.7411458281249999",
            "Destination": "ABC"
        },
        "rank_0": {
            "Source": "LMN",
            "Weight": "0.994583325",
            "Destination": "PQR"
        }
     }
}   

我理解的是我需要一个具有对象结构的对象类。目前我只是尝试使用rank对象,但未能形成所需的JSON。

我的对象结构代码:

public class Object {
    int rank_;

    public class Inner{
        String Source;
        String Destination;
        String Weightage;
    }
}

我可以将Object的实例或Inner的实例传递给toJson()方法,这样我就可以获得{"rank_":1}{"Source":"ABC","Destination":"XYZ","Weightage":"123"}。 我似乎无法将每个内部对象放到相应的排名对象中。

我使用org.json相对轻松地完成了它,但该库与Android studio存在一些问题,所以我不得不切换到Gson。我之前做过的(也有效)是:

public JSONObject convertToJson(int mkr, String[][] result){
    JSONObject outerObj = new JSONObject();
    JSONObject innerObj = new JSONObject();
    JSONObject[] temp = new JSONObject[mkr];
    outerObj.put("totalSuggestions", marker); 
    outerObj.put("routes",innerObj);

    for (int i=0;i<marker;i++){ 
       String[] useless = result[i][0].split("-"); 
       temp[i]= new JSONObject();
       temp[i].put("Source",useless[0] );
       temp[i].put("Destination", useless[1]);
       temp[i].put("Weight", result[i][1]);
       innerObj.put("rank_"+i, temp[i]);
    }
    System.out.println(outerObj.toString());
    return outerObj;
}

3 个答案:

答案 0 :(得分:3)

嗯,首先:相关对象可能应该在一个类中。所以让我们从一个简单的类开始:

public class Results {
  int mkr;
  String[][] result;
}

现在我们要序列化它。我们可以构建一个不同的数据结构,或者我们可以编写自己的自定义序列化程序。我们希望自定义类允许我们使用Gson类型推断来执行此操作,而且代码更容易理解。我将向您展示如何序列化数据结构,并且我将反序列化作为练习留给您。

我们创建了一个TypeAdapter<Results>

public class ResultsAdapter extends TypeAdapter<Results> {
  public Results read(JsonReader reader) throws IOException {
    if (reader.peek() == JsonToken.NULL) {
      reader.nextNull();
      return null;
    }
    // exercise for you
    return results;
  }
  public void write(JsonWriter writer, Results value) throws IOException {
    if (value == null) {
      writer.nullValue();
      return;
    }
    writer.beginObject();
    writer.name("totalSuggestions").value(value.mkr);
    writer.name("routes");
    writer.beginObject();
    for(int i = 0; i < value.mkr; i++) {
       writer.name("rank_"+i);
       writer.beginObject();
       String[] sourceDestSplit = result[i][0].split("-"); 
       writer.name("Source").value(sourceDestSplit[0]);
       writer.name("Destination").value(sourceDestSplit[1]);
       writer.name("Weight").value(result[i][1]);
       writer.endObject();
    }
    writer.endObject();
    writer.endObject();
  }
}

然后您可以通过执行来调用此方法(注意:应该只创建一次Gson对象,但我这样做是为了保持代码简短):

public String convertToJson(Results results) {
   GsonBuilder builder = new GsonBuilder();
   builder.registerTypeAdapter(new ResultsAdapter()):
   Gson gson = builder.build();

   return gson.toJson(results);
}

这会以您提出的方式为您服务,但我强烈建议您使用JSON's array syntax(使用[])。试试这个:

  public void write(JsonWriter writer, Results value) throws IOException {
    if (value == null) {
      writer.nullValue();
      return;
    }
    writer.beginObject();
    writer.name("totalSuggestions").value(value.mkr);
    writer.name("routes");
    writer.beginArray();
    for(int i = 0; i < value.mkr; i++) {
       writer.beginObject();
       String[] sourceDestSplit = result[i][0].split("-"); 
       writer.name("Source").value(sourceDestSplit[0]);
       writer.name("Destination").value(sourceDestSplit[1]);
       writer.name("Weight").value(result[i][1]);
       writer.endObject();
    }
    writer.endArray();
    writer.endObject();
  }

这样做将导致JSON看起来像这样,在另一方面更容易反序列化并迭代,因为你不必动态生成密钥的映射。:

{
  "totalSuggestions": 6,
  "routes": [
    {
        "Source": "ABC",
        "Weight": "0.719010390625",
        "Destination": "XYZ"
    },
    {
        "Source": "XYZ",
        "Weight": "0.7411458281249999",
        "Destination": "ABC"
    },
    {
        "Source": "LMN",
        "Weight": "0.994583325",
        "Destination": "PQR"
    }
  ]
}   

答案 1 :(得分:0)

为了记录,这就是我所做的。

import java.util.*;


public class DataObject {

public int Suggestions;
HashMap<String, route> routes = new HashMap<>();

    //constructor
    public DataObject(int mkr, String[][] routesArr){
        Suggestions = mkr;
        { 
            for (int i=0;i<Suggestions;i++){
                routes.put("rank_"+(i+1),new route(routesArr[i]));
            }
        }
    }     
//class to populate the hashmap
public class route{
    public String Origin;
    public String Destination;
    public String Weight; 


public route(String arr[]){
    String[] splitter = arr[0].split("-");
    this.Origin = splitter[0];
    this.Destination = splitter[1];
    this.Weight = arr[1];
}     

}
}

答案 2 :(得分:0)

我在这里寻找com.google.gson.JsonObject库的类似解决方案时登陆。现在,我找到了:

JsonObject mainJson = new JsonObject();
JsonObject innerJson = new JsonObject();

innerJson.addProperty("@iot.id", "31");
mainJson.add("Datastream", innerJson);  // <-- here the nesting happens
mainJson.addProperty("result", 12.3);

// fetch inner variable like this
System.out.println(mainJson.get("Datastream").getAsJsonObject().get("@iot.id").getAsString());

使用com.google.gson.JsonObject库对我来说很好。

相关问题