2014-02-24 66 views
0

我無法弄清楚爲什麼當嘗試序列化一個對象時,我得到一個與反序列化相關的異常。我的目標有一個字段是喬達型LocalDateTime嘗試序列化時傑克遜反序列化異常

.... 
ObjectMapper mapper = new ObjectMapper(); 
mapper.writeValueAsString(response)); 

的我得到了以下異常:

org.codehaus.jackson.map.JsonMappingException:java.lang.String中不能轉換爲org。 joda.time.LocalDateTime

我想序列化。爲什麼它試圖將字符串值轉換爲對象?我試圖添加自定義的反序列化器,但它不起作用。

更新更多異常的:

org.codehaus.jackson.map.JsonMappingException:java.lang.String中不能轉換到org.joda.time.LocalDateTime(通過參考鏈:com.my .AcountDetailResponse [「registrationDate」]) at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] at org。 codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] at org.codehaus.jackson.map.ser.std.SerializerBase。 wrapAndThrow(SerializerBase.java:140)〜[jackson-mapper-asl-1.9.1 3.jar:1.9.13] at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] at org.codehaus.jackson.map。org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] 。 ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java: 256)〜[jackson-mapper-asl-1.9.13.jar:1.9.13] at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575)〜[jackson-mapper-asl-1.9。 13.jar:1.9.13] at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097)〜[jackson-mapper-asl-1.9.13.jar:1 .9.13]

嘗試添加解串器:

CustomDeserializerFactory deserializerFactory = new CustomDeserializerFactory(); 
    deserializerFactory.addSpecificMapping(LocalDateTime.class, new CustomLocalDateTimeDeserializer()); 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.setDeserializerProvider(new StdDeserializerProvider(deserializerFactory)); 
    try { 
     remoteActionDto.setPayload(mapper.writeValueAsString(response)); 
    } catch (IOException e) { 
     logger.error("Can not convert response to json!", e); 
     ..... 
    } 

解串器本身。我並沒有真正轉換,而只是概念證明:

private static class CustomLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> { 

    @Override 
    public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     return new LocalDateTime(); 
    } 
} 
+0

更多的代碼和更多的例外情況是不錯的。您是如何嘗試添加客戶(de)序列化器的?例外發生在哪裏? –

+0

我添加了更多的信息,但是讓我瘋狂的東西是爲什麼當我嘗試做相反的事情時,它會嘗試將字符串轉換爲對象! – Nikolay

回答

0

我寫了一個快速測試課來檢查你提供了什麼。它看上去一切正常,輸出如下:

{"value":[2014,2,24,13,42,44,745]} 

當然,這可能不是你要找的具體格式,但無論哪種方式,這裏是類:

public class JsonSerialization { 

    public static void main(final String[] args) { 
     try { 
      final Response response = new Response(); 

      final ObjectMapper mapper = new ObjectMapper(); 
      final String value = mapper.writeValueAsString(response); 
      System.out.println(value); 
     } 
     catch (final Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static class Response { 
     LocalDateTime value = new LocalDateTime(); 
     public LocalDateTime getValue() { 
      return this.value; 
     } 
     public void setValue(final LocalDateTime value) { 
      this.value = value; 
     } 
    } 
}   

我猜這引發了以下問題:

  • 您是否有LocalDateTime屬性的獲取者和設置者(registrationDate)?
  • 您確定發生了錯誤,您認爲它發生了嗎?例外只是關於傑克遜的一部分,它在哪裏說writeValueAsString方法在之內被調用您的代碼?

我知道這是不是你的問題的一部分,但是在傑克遜的1.9.13,你應該定製註冊像這樣(反)序列:

SimpleModule module = new SimpleModule("", new Version(1, 0, 0, ""); 
module.addDeserializer(LocalDateTime.class, new CustomLocalDateTimeDeserializer()); 
ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(module); 
0

我發現這個問題(或者實際上是我的同事做的)。這是我見過的最愚蠢的java行爲。問題是,包含LocalDateTime字段的DTO通過反映填充,並且似乎可以成功設置String類型的值。當您嘗試使用此字段(不是在設置時)時,會發生類別強制異常。

public class MyDto { 
    // trough reflection, the contained object is a java.lang.String 
    private LocalDateTime myDate; 
} 

如果你問爲什麼會這樣 - 因爲我們沒有配置轉換爲LocalDateTime,但DateTime來代替。我的同事錯誤地使用了LocalDateTime,傑克遜以靜默方式將其反序列化爲String

+0

我不認爲有可能以這種方式在'LocalDateTime'上分配'String'。 JVM會阻止這一點。然而,泛型是可能的:如果type用類型參數聲明爲'T',那麼在內部它將被表示爲'java.lang.Object'(或者如果綁定,下限類型),並且該賦值會嘗試訪問值時繼續併產生異常。 – StaxMan

0

用JodaModule模塊註冊您的映射器。

mapper.register(new JodaModule()) 

或試圖JodaMapper:

import com.fasterxml.jackson.datatype.joda.JodaMapper; 

public static void main(String args[]){ 
    DateTime dateTime = new DateTime(12353434); 
    JodaMapper mapper = new JodaMapper(); 
    try { 
     serializedString = mapper.writeValueAsString(dateTime); 
     System.out.println(serializedString); 
    } catch (JsonProcessingException e) { 
     e.printStackTrace(); 
    } 
} 

控制檯輸出:

12353434