Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get JSON element type with Gson?

In a JSON file, each object inside the file is composed by different type of JSON elements. (integer, string, array, array of objects, etc.)

My target is to list all element name and corresponding type. May I know how can I do that in Gson? The purpose of this is for creating a Hive schema.

Example:

{
  "number": 1, 
  "ts": "1386848002", 
  "cmpg": [
    {
      "id": 476, 
      "mcp": 0, 
      "deals": [ ], 
      "cookie": "uid:123", 
      "bid": [
        {
          "bId": 0, 
          "status": "ZB", 
          "rmtchID": -1
        }
      ]
    }
  ]
}

Output:

number int,
ts String,
cmpg array<map<String, Object>> // not sure how to interpret this...
like image 534
Kevin Avatar asked Dec 17 '13 01:12

Kevin


1 Answers

I wrote this simple class that shows you how use some Gson classes to get what you need.

package stackoverflow.questions.q19124387;

import java.util.Map;

import com.google.gson.*;

public class Q20624042 {

   private static String printClass(JsonElement je, String ident) {
      StringBuilder sb = null;
      if (je.isJsonNull())
         return "null";

      if (je.isJsonPrimitive()) {
         if (je.getAsJsonPrimitive().isBoolean())
            return "Boolean";
         if (je.getAsJsonPrimitive().isString())
            return "String";
         if (je.getAsJsonPrimitive().isNumber()){
            return "Number";
         }
      }

      if (je.isJsonArray()) {
         sb = new StringBuilder("array<");
         for (JsonElement e : je.getAsJsonArray()) {
            sb.append(printClass(e, ident+ "    "));
         }
         sb.append(">");
         return sb.toString();
      }

      if (je.isJsonObject()) {
         sb = new StringBuilder("map<\n");
         for (Map.Entry<String, JsonElement> e : je.getAsJsonObject().entrySet()) {
            sb.append(ident);
            sb.append(e.getKey()).append(":");
            sb.append(printClass(e.getValue(), ident+"   "));
            sb.append("\n");
         }
         sb.append(ident);
         sb.append(">");
         return sb.toString();
      }
      return "";

   }

   public static void main(String[] args) {
      String json = "{" + "\"number\":1," + "\"ts\":\"1386848002\"," + "\"cmpg\":[{\"id\":476,\"mcp\":0.0000,\"deals\":[],\"cookie\":\"uid:123\",\"bid\":[{\"bId\":0,\"status\":\"ZB\",\"rmtchID\":-1}]}]}";

      JsonElement je = new JsonParser().parse(json);
      System.out.println(printClass(je,"   "));

   }

}

And this is the result with your JSON string:

map<
   number:Number
   ts:String
   cmpg:array<map<
          id:Number
          mcp:Number
          deals:array<>
          cookie:String
          bid:array<map<
                 bId:Number
                 status:String
                 rmtchID:Number
                 >>
   >>
  >

JSON has a recursive nature, so the only way to approach to this kind of problem is to write a recursive method. My indentation system is quite naive, I put indentation only to show the correspondence to your JSON, maybe you do not even need that. Keep in mind that in JSON you do not have difference between integer and doubles,

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays)

so if you what that distinction you have change a bit my method.

.

like image 108
giampaolo Avatar answered Sep 30 '22 01:09

giampaolo