简体   繁体   English

如何使用 Gson 制作嵌套的 JSON 对象?

[英]How do I make nested JSON Objects using Gson?

I have written a program that does some probability calculations and gives its results in the form of arrays.我编写了一个程序来进行一些概率计算并以数组的形式给出其结果。 I want to convert these results to JSON format, but I am having issues.我想将这些结果转换为 JSON 格式,但我遇到了问题。

I want my json object to look like this:我希望我的 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"
        }
     }
}   

What I understood is that I need to have an object class with the structure of my objects.我的理解是,我需要一个包含对象结构的对象类。 For now I am experimenting with the rank object only but failing to form the required JSON.现在我只试验 rank 对象,但未能形成所需的 JSON。

My code for the object structure:我的对象结构代码:

public class Object {
    int rank_;

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

I can pass either an instance of Object or an instance of Inner to toJson() method so I either get {"rank_":1} or {"Source":"ABC","Destination":"XYZ","Weightage":"123"} .我可以将Object的实例或Inner的实例传递给toJson()方法,因此我可以得到{"rank_":1}{"Source":"ABC","Destination":"XYZ","Weightage":"123"} I cant seem to put each of the inner object to the corresponding rank object.我似乎无法将每个内部对象放到相应的等级对象中。

I did it with relative ease with org.json but that library has some issues with Android studio so I had to switch to Gson.我使用org.json相对轻松地org.json但该库在 Android Studio 中存在一些问题,因此我不得不切换到 Gson。 What I did earlier (which worked as well) was:我之前所做的(也有效)是:

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;
}

Well, first: related objects should probably be in a class together.嗯,首先:相关的对象可能应该一起在一个类中。 So lets start with a simple class:所以让我们从一个简单的类开始:

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

Now we want to serialize it.现在我们要序列化它。 We could construct a different data structure, or we could just write our own custom serializer.我们可以构建不同的数据结构,或者我们可以编写自己的自定义序列化程序。 We want to have our custom class to allow us to use Gson 's type inference for doing so, plus the code is just easier to understand.我们希望有我们的自定义类来允许我们使用Gson的类型推断来这样做,而且代码更容易理解。 I will show you how to serialize the data structure, and I'll leave the deserialization as an exercise for you.我将向您展示如何序列化数据结构,并将反序列化留给您作为练习。

We create a TypeAdapter<Results> :我们创建一个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();
  }
}

You can then call this method by doing (note: should only create the Gson object once, but I did it this way to keep the code short):然后你可以通过执行调用这个方法(注意:应该只创建一次Gson对象,但我这样做是为了保持代码简短):

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

   return gson.toJson(results);
}

This will work you the way you've asked, but I strongly recommend using JSON's array syntax instead (using [] ).这将按照您要求的方式工作,但我强烈建议您改用JSON 的数组语法(使用[] )。 Try this instead:试试这个:

  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();
  }

Doing it this will will result in JSON that looks like this, which will be easier to deserialize on the other side and iterate through, because you won't have to dynamically generate maps for the keys.:这样做将导致 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"
    }
  ]
}   

I landed here while searching for a similar solution for the com.google.gson.JsonObject library.我在为com.google.gson.JsonObject库搜索类似解决方案时来到这里。 Now, I've found it:现在,我找到了:

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());

This works fine for me using the com.google.gson.JsonObject library.这对我使用com.google.gson.JsonObject库很有效。

For the record, this is what i did.为了记录,这就是我所做的。

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];
}     

}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM