2011-07-27 22 views
3

使用gson,是否可以僅在某些字段上使用自定義解串器/序列化程序? user guide顯示如何爲整個類型註冊適配器,而不是用於特定字段。我之所以要這樣做,是因爲我解析了自定義日期格式並將其存儲在long成員字段中(作爲Unix時間戳),所以我不想爲所有Long字段註冊類型適配器。僅在特定字段上使用自定義解串器?

有沒有辦法做到這一點?

回答

5

我還將日期值作爲long存儲在我的對象中,以便於防禦性複製。我還希望在序列化對象時僅覆蓋日期字段,而不必寫出流程中的所有字段。這是我想出的解決方案。不知道這是處理這個問題的最佳方法,但它似乎表現得很好。

DateUtil類是一個自定義類,在這裏用於獲得解析爲StringDate

public final class Person { 
    private final String firstName; 
    private final String lastName; 
    private final long birthDate; 

    private Person(String firstName, String lastName, Date birthDate) { 
    this.firstName = firstName; 
    this.lastName = lastName; 
    this.birthDate = birthDate.getTime(); 
    } 

    public static Person getInstance(String firstName, String lastName, Date birthDate) { 
    return new Person(firstName, lastName, birthDate); 
    } 

    public String toJson() { 
    return new GsonBuilder().registerTypeAdapter(Person.class, new PersonSerializer()).create().toJson(this); 
    } 

    public static class PersonSerializer implements JsonSerializer<Person> { 
    @Override 
    public JsonElement serialize(Person person, Type type, JsonSerializationContext context) { 
     JsonElement personJson = new Gson().toJsonTree(person); 
     personJson.getAsJsonObject().add("birthDate", new JsonPrimitive(DateUtil.getFormattedDate(new Date(policy.birthDate), DateFormat.USA_DATE))); 
     return personJson; 
    } 
    } 
} 

當類是串行化的,所述birthDate字段被返回作爲格式化的String代替long值。

+0

與此相關的問題是委託的新Gson()。如果我可以使用現有的gson(除了這種類型的適配器,它可能有自己的定製),那將是一個完美的解決方案。有任何想法嗎? – Mar0ux

+0

@ Mar0ux,我明白了你的觀點。除非'Gson'對象是這個類的靜態成員,否則我真的不知道它是如何工作的。我現在不再使用Gson了。自從與Spring有良好的整合以來,我已經轉向傑克遜。 – Jason

1

請勿將其存儲爲long,請使用具有適當適配器的自定義類型。在你的類型中,以任何你想要的方式來表示你的數據 - 一個long,爲什麼不。

+0

我曾考慮過這個問題,但我認爲在Long上編寫一個包裝有點麻煩。 – Felix

+0

這不是一個包裝。從語義上講,你的實際對象不是一個長整數。從OOP的角度來看,使用long來表示它應該是一個與外部代碼無關的內部實現細節。直接使用long將*解包*。 – slezica

+0

我要存儲的數據是自1970年1月1日以來的毫秒數。而且,從語義上講,這是一個長整數。 – Felix