java - 反序列化GSON中的递归多态类

标签 java json deserialization gson

class Complex implements Recursive {
  Map<String, Recursive> map;
  ...
}

class Simple implements Recursive { ... }

如何反序列化这个 json:

{
  "type" : "complex",
  "map" : {
     "a" : {
        "type" : "simple"
     },
     "b" : {
        "type" : "complex",
        "map" : {
            "ba" : {
                "type" : "simple"
        } 
     } 
  }
}

使用谷歌 GSON?

最佳答案

要反序列化您的 JSON,您需要为递归接口(interface)使用自定义反序列化器。在那种类中,您需要检查 JSON 并决定将哪种类实例化为 JSON 本身的类型字段。这里有一个我为您编写的基本反序列化器示例。

当然可以改进管理边界情况(例如,如果您没有类型字段会发生什么?)。

package stackoverflow.questions;

import java.lang.reflect.Type;
import java.util.*;

import stackoverflow.questions.Q20254329.*;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

public class Q20327670 {

   static class Complex implements Recursive {
      Map<String, Recursive> map;

      @Override
      public String toString() {
         return "Complex [map=" + map + "]";
      }

   }

   static class Simple implements Recursive {

      @Override
      public String toString() {
         return "Simple []";
      }
   }

   public static class RecursiveDeserializer implements JsonDeserializer<Recursive> {

      public Recursive deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
         Recursive r = null;
         if (json == null)
            r = null;
         else {
            JsonElement t = json.getAsJsonObject().get("type");
            String type = null;
            if (t != null) {
               type = t.getAsString();

               switch (type) {
               case "complex": {
                  Complex c = new Complex();
                  JsonElement e = json.getAsJsonObject().get("map");
                  if (e != null) {
                     Type mapType = new TypeToken<Map<String, Recursive>>() {}.getType();
                     c.map = context.deserialize(e, mapType);
                  }
                  r = c;
                  break;
               }
               case "simple": {
                  r = new Simple();
                  break;
               }
               // remember to manage default..
               }

            }
         }
         return r;
      }

   }

   public static void main(String[] args) {
      String json = " {                                         " + 
                    "    \"type\" : \"complex\",                " + 
                    "    \"map\" : {                            " + 
                    "       \"a\" : {                           " +
                    "          \"type\" : \"simple\"            " +
                    "       },                                  " + 
                    "       \"b\" : {                           " +
                    "          \"type\" : \"complex\",          " + 
                    "          \"map\" : {                      " + 
                    "              \"ba\" : {                   " +
                    "                  \"type\" : \"simple\"    " +
                    "          }                                " +
                    "       }                                   " +
                    "    }                                      " +
                    "  }  }                                     ";

      GsonBuilder gb = new GsonBuilder();
      gb.registerTypeAdapter(Recursive.class, new RecursiveDeserializer());

      Gson gson = gb.create();
      Recursive r = gson.fromJson(json, Recursive.class);

      System.out.println(r);

   }

}

这是我的代码的结果:

Complex [map={a=Simple [], b=Complex [map={ba=Simple []}]}]

关于java - 反序列化GSON中的递归多态类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20327670/

相关文章:

php - 如何显示Mysql php结果json格式?

java - 如何使用 Java 和 Jackson 库反序列化 Json 字符串以获得多态结果?

android - 在对象中使用 Gson 反序列化 JSON

java - 如何在Java中将PostgreSQl View 与hibernate连接?

python - 自定义Python JSON object_hook

javascript - 解释 json 字符串中的反斜杠字符以实现漂亮的显示

java - Java从二进制文件中读取字符串

java - @AspectJ 以注解作为方法参数的类级注解建议

java - Nifi-1.0.0 和 Crate.IO

在 Java 中使用 filewriter 打开文件时出现 java.io.FileNotFoundException