com.fasterxml.jackson.databind.exc.InvalidFormatException

    技术2023-07-24  78

    目录

    异常描述

    错误位置初现

    追根溯源

    解决过程

    解决方案


     

     

    异常描述:

    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

     

    Processed: 0.008, SQL: 9