2011-05-23 7 views
39

У меня есть класс Java, Пользователь:Как написать собственный десериализатор JSON для Gson?

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

И я получаю список 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)); 
} 

Но мой десериализатор не работает. Как я могу написать собственный десериализатор JSON для Gson?

+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

Я хотел бы сделать несколько иной подход, чтобы минимизировать «ручной» анализ в моем коде, поскольку излишнее выполнение в противном случае несколько поражает цель, почему я использую API, такой как Gson, в первую очередь.

// 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

Я определенно предпочитаю эту модель - если Timestamp - единственное, что не удается разобрать, лучше сделать десериализацию Timestamp, а не вручную анализировать весь объект User, когда Gson уже вполне способен это сделать. – dimo414

+0

маленький редактирование. мы можем использовать «return new Timestamp (json.getAsLong()); вместо «long time = Long.parseLong (json.getAsString()); возвращает новую временную метку (время); – Nishanth

+0

Вы также можете обработать цепочку 'GsonBuilder', улучшая читаемость. –