com.fasterxml.jackson.databind.exc.InvalidFormatException

目錄

異常描述

錯誤位置初現

追根溯源

解決過程

解決方案


 

 

  • 異常描述:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2020-06-29T02:49:17.340+0000": not a valid representation (error: Failed to parse Date value '2020-06-29T02:49:17.340+0000': Unparseable date: "2020-06-29T02:49:17.340+0000")
 at [Source: (String)"{"models":[{"id":"754a1728-a539-11ea-8ce9-c01885024e2c","name":"model_request","version":3,"modelType":0,"description":"model_request","stencilSetId":null,"createdBy":"admin","lastUpdatedBy":"bpmUser","lastUpdated":"2020-06-29T02:49:17.340+0000"}],"name":"bpm_dev","key":"bpm_dev","theme":"theme-4","icon":"glyphicon-asterisk","groupsAccess":"manager"}"; line: 1, column: 216] (through reference chain: org.flowable.ui.modeler.domain.AppDefinition["models"]->java.util.ArrayList[0]->org.flowable.ui.modeler.domain.AppModelDefinition["lastUpdated"])
	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1676)
	at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:932)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:550)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:491)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:195)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:285)
	at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:268)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
	at org.ups.modules.bpm.controller.RegisterApprovalController.testTime(RegisterApprovalController.java:200)


反序列化失敗字段:lastUpdated (java.util.Date)
反序列化失敗值:2020-06-29T02:49:17.340+0000
  • 錯誤位置初現:

僞代碼:類中注入objectMapper
@Autowired
private ObjectMapper objectMapper;

僞代碼:方法中調用objectMapper.readValue() 反序列化json
AppDefinition appDefinition = null;
try {
    appDefinition = objectMapper.readValue(json, AppDefinition.class);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}
  • 追根溯源:

com.fasterxml.jackson.databind.DeserializationContext#parseDate():705行

public Date parseDate(String dateStr) throws IllegalArgumentException
{
   try {
        DateFormat df = getDateFormat();
        return df.parse(dateStr);
   } catch (ParseException e) {
        throw new IllegalArgumentException(String.format(
                    "Failed to parse Date value '%s': %s", dateStr,
                    ClassUtil.exceptionMessage(e)));
   }
}

在這裏拋出異常IllegalArgumentException

發現這裏df 獲取的DateFormat的實現是 SimpleDateFormat,
formatdate是 “yyyy-MM-dd HH:mm:ss” 
而需要反序列化的日期是 “2020-06-29T02:49:17.340+0000” 因此反序列化失敗
  • 解決過程:

    經測試發現 當創建ObjectMapper時 
    
    1.如果使用無參構造創建:
    ObjectMapper objectMapper = new ObjectMapper();
    
    則DeserializationConfig中_base._dateFormat 是 StdDateFormat
    
    2.如果使用注入創建
    @Autowired
    private ObjectMapper objectMapper;
    
    則DeserializationConfig中_base._dateFormat 是 SimpleDateFormat
    
    使用注入創建時,會在spring-boot-autoconfigure包下的JacksonAutoConfiguration 中獲取bean
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration#305
    
    @Bean
    @Primary
    @ConditionalOnMissingBean
    ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
         return builder.createXmlMapper(false).build();
    }
    
    

    解決方案:

1.創建ObjectMapper時 使用構造函數創建 即new出一個ObjectMapper

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章