2011-05-23 68 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