2011-05-23 67 views
39

我有一个Java类,用户:如何为Gson编写自定义JSON解串器?

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

我收到包含来自web服务的用户对象上JSON列表:

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

我曾尝试编写自定义解串器:

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

但我的反序列化器不起作用。我怎样才能为Gson编写一个定制的JSON解串器?

+0

这是否例如帮助呢? http://stackoverflow.com/questions/5845822/gson-deserializing-key-value-to-custom-object – 2011-05-23 12:17:33

+0

你是什么意思它“不起作用”?有什么问题? – ColinD 2011-05-23 13:25:52

+1

“date_date”应该是“update_date”吗? – 2011-06-01 17:39:03

回答

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

我假设用户类具有适当的构造函数。

74

我会采取稍微不同的方法如下,以尽量减少我的代码中的“手动”解析,因为不必要的做法会有点失败,为什么我会首先使用像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); 
    } 
} 

(这里假定 “date_date” 应为 “UPDATE_DATE”,在原来的问题。)

+2

我绝对更喜欢这种模式 - 如果时间戳是唯一不能解析的东西,那么最好是使时间戳反序列化,而不是手动解析整个用户对象,当时Gson已经完全有能力这样做。 – dimo414 2012-10-19 13:14:02

+0

小编辑。我们可以使用“return new Timestamp(json.getAsLong());”而不是“long time = Long.parseLong(json.getAsString()); 返回新的时间戳(time);” – Nishanth 2016-01-07 20:53:12

+0

你也可以通过方法链接'GsonBuilder',提高可读性。 – 2017-09-11 12:43:04