2012-11-17 25 views
2

我有一個代表問卷的對象結構,我需要序列化爲JSON。 結構的一個類是OpenQuestion,此類使用具有兩個參數的泛型。 當使用的類型之一是Date時,該問題開始,日期序列化錯誤,如long。使用傑克遜泛型到JSON的Serialize類

類代碼:

public class OpenQuestion <valueType,validationType> extends AbstractQuestion implements Serializable { 
    private valueType value; 
    private validationType minValue; 
    private validationType maxValue; 
    ... 
} 

我看到如何序列日期在哈希表,如果散列圖總是使用日期,但在這種情況下,我用字符串,整數或日期的類。

任何想法解決它? 謝謝

+1

您是否做過任何搜索?我很快發現我沒有使用傑克遜,但一個快速搜索導致我http://wiki.fasterxml.com/JacksonFAQDateHandling:'objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);' –

+2

是的,但我認爲問題在於使用泛型的反序列化器,因爲Jackson不知道這是一個日期還是什麼 – James2707

回答

1

正如@MiserableVariable所指出的,傑克遜默認情況下將(大部分)日期字段序列化爲(數字長)時間戳。您可以通過多種方式覆蓋此行爲。

如果使用自己的ObjectMapper的情況下,重寫一個屬性寫日期爲ISO-8601:

objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); 

如果使用自己的ObjectMapper的情況下,有寫在自己的自定義格式的日期:

objectMapper.setDateFormat(myDateFormat); // 1.8 and above 
objectMapper.getSerializationConfig().setDateFormat(myDateFormat); // for earlier versions (deprecated for 1.8+) 

離開對於大多數字段的默認序列化行爲,但覆蓋它在某些對象的某些字段,可使用自定義序列:

public class MyBean implements Serializable { 
    private Date postDate; 

    // ... constructors, etc 

    @JsonSerialize(using = MyCustomDateSerializer.class) 
    public Date getPostDate() { 
     return postDate; 
    } 
} 

public class MyCustomDateSerializer extends JsonSerializer<Date> { 

    @Override 
    public void serialize(final Date date, final JsonGeneraror generator, 
      final SerializerProvider provider) throws IOException, 
      JSONProcessingException { 

     generator.writeString(yourRepresentationHere); 
    } 
} 

所有這些信息都可以在Jackson Documentation中找到,其中大部分信息在section中處理日期處理。

+0

好吧,這解決了串行化數據的問題。但是當我需要反序列化它時,這有效嗎?請記住我使用泛型,傑克遜如何知道這需要在Date中反序列化而不是字符串?感謝您的幫助 – James2707

2

您可以爲此添加JsonTypeInfo註釋。有兩種使用方式:

  • 獲取它自動添加一個類型註釋到你的對象,所以它知道什麼將其反序列化爲。
  • 添加自定義類型解析器,爲您處理此問題。

第一個會讓你的JSON變醜,但只需要很少的額外代碼,並不會強制你製作自定義序列化器。後者更困難,但會導致更乾淨的JSON。總的來說,問題的部分原因是你的一個類型不是用JSON(Date)建模的,所以你可能需要將它在JSON文件中作爲整數或字符串類型進行序列化。

前一種選擇看起來有點像這樣:

@JsonTypeInfo(use = Id.CLASS, include = As.WRAPPER_PROPERTY) 
private valiationType minValue; 

應該編碼說,一個字符串值,就像這樣:對被準確的,因爲這

{ __type = "java.lang.String", value = "Hello, World" } 

沒有承諾主要來自內存!

+0

錯誤,使用JsonTypeInfo不能解決OP的問題。 – Perception

+1

謝謝!這解決了問題! – James2707

+0

@Perception:我認爲OP的兩個參數是反序列化時間未知類型的主要問題,但是我從你的回答可以看出,如果沒有定製,日期格式化也是「有點垃圾」的問題。這兩個答案是必需的,以獲得一個「漂亮」(有很好的日期)和明確的可解析的響應:) – Calum

2

這取決於。如果你知道預期的類型,你只是通過泛型類型參考:

OpenQuestion<Value,Validation> v = objectMapper.readValue(json, 
    new TypeReference<OpenQuestion<Value,Validation>>() { }); 

爲線索傑克遜在爲預期的類型。

如果您不知道,那麼其他答案顯示如何使用@JsonTypeInfo

+0

這真是一個好點!我完全忘記了這個功能,但在某些情況下它確實有意義。 – Calum