2011-05-23 1 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 –

+0

「動作しません」とはどういう意味ですか?問題は何ですか? – ColinD

+1

"date_date"を "update_date"にする必要がありますか? –

答えて

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がすでに完全にそうすることができる時、手動でUserオブジェクト全体を解析するのではなく、Timestampが構文解析に失敗した唯一のものであれば、Timestampをdeserializableにするのがよい。 – dimo414

+0

小さな編集。 "return new Timestamp(json.getAsLong());"を使うことができます。 "long time = Long.parseLong(json.getAsString()); return新しいタイムスタンプ(時刻);" – Nishanth

+0

また、 'GsonBuilder'をメソッドチェーンして読みやすくすることもできます。 –

関連する問題