How do I write a custom JSON deserializer for Gson

2018-12-31 13:37发布

问题:

I have a Java class, User:

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

And I receive a JSON list containing user objects from a webservice:

[{\"id\":1,\"name\":\"Jonas\",\"update_date\":\"1300962900226\"},
{\"id\":5,\"name\":\"Test\",\"date_date\":\"1304782298024\"}]

I have tried to write a custom deserializer:

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

But my deserializer doesn\'t work. How can I write a custom JSON deserializer for Gson?

回答1:

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

I\'m assuming User class has the appropriate constructor.



回答2:

I\'d take a slightly different approach as follows, so as to minimize \"manual\" parsing in my code, as unnecessarily doing otherwise somewhat defeats the purpose of why I\'d use an API like Gson in the first place.

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

(This assumes that \"date_date\" should be \"update_date\", in the original question.)