如何为Gson编写自定义JSON反序列化器?

Jon*_*nas 47 java json gson deserialization

我有一个Java类,用户:

public class User
{
    int id;
    String name;
    Timestamp updateDate;
}
Run Code Online (Sandbox Code Playgroud)

我收到一个包含来自Web服务的用户对象的JSON列表:

[{"id":1,"name":"Jonas","update_date":"1300962900226"},
{"id":5,"name":"Test","date_date":"1304782298024"}]
Run Code Online (Sandbox Code Playgroud)

我试图编写一个自定义反序列化器:

@Override
public User deserialize(JsonElement json, Type type,
                        JsonDeserializationContext context) throws JsonParseException {

        return new User(
            json.getAsJsonPrimitive().getAsInt(),
            json.getAsString(),
            json.getAsInt(),
            (Timestamp)context.deserialize(json.getAsJsonPrimitive(),
            Timestamp.class));
}
Run Code Online (Sandbox Code Playgroud)

但我的解串器不起作用.如何为Gson编写自定义JSON反序列化器?

Pro*_*uce 84

我采取了一种稍微不同的方法,如下所示,以便最小化我的代码中的"手动"解析,因为不必要的做法在某种程度上违背了为什么我首先使用像Gson这样的API的目的.

// output:
// [User: id=1, name=Jonas, updateDate=2011-03-24 03:35:00.226]
// [User: id=5, name=Test, updateDate=2011-05-07 08:31:38.024]

// using java.sql.Timestamp

public class Foo
{
  static String jsonInput = 
    "[" +
      "{\"id\":1,\"name\":\"Jonas\",\"update_date\":\"1300962900226\"}," +
      "{\"id\":5,\"name\":\"Test\",\"update_date\":\"1304782298024\"}" +
    "]";

  public static void main(String[] args)
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
    gsonBuilder.registerTypeAdapter(Timestamp.class, new TimestampDeserializer());
    Gson gson = gsonBuilder.create();
    User[] users = gson.fromJson(jsonInput, User[].class);
    for (User user : users)
    {
      System.out.println(user);
    }
  }
}

class User
{
  int id;
  String name;
  Timestamp updateDate;

  @Override
  public String toString()
  {
    return String.format(
      "[User: id=%1$d, name=%2$s, updateDate=%3$s]",
      id, name, updateDate);
  }
}

class TimestampDeserializer implements JsonDeserializer<Timestamp>
{
  @Override
  public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    long time = Long.parseLong(json.getAsString());
    return new Timestamp(time);
  }
}
Run Code Online (Sandbox Code Playgroud)

(这假设原始问题中"date_date"应为"update_date".)

  • 我绝对更喜欢这个模型 - 如果Timestamp是唯一无法解析的东西,最好使Timestamp可反序列化,而不是手动解析整个User对象,当Gson已经完全能够这样做时. (3认同)

Pet*_*ego 51

@Override
public User deserialize(JsonElement json, Type type,
        JsonDeserializationContext context) throws JsonParseException {

    JsonObject jobject = json.getAsJsonObject();

    return new User(
            jobject.get("id").getAsInt(), 
            jobject.get("name").getAsString(), 
            new Timestamp(jobject.get("update_date").getAsLong()));
}
Run Code Online (Sandbox Code Playgroud)

我假设User类有适当的构造函数.