错误场景

用Spring boot写了一个简单的RESTful API,在测试POST请求的时候,request body是一个符合对应实体类要求的json串,post的时候报错。

先贴一段error log:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.yucfeng.Entity.EData` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 2, column: 2]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1290) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326) ~[jackson-databind-2.9.5.jar:2.9.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.5.jar:2.9.5]

先说结论

原因:

原因是我在该实体类中添加了一个为了方便实例化该类用的构造函数,导致JVM不会添加默认的无参构造函数,而jackson的反序列化需要无参构造函数,因此报错。

Response实体类同理。

解决:

在实体类中补上一个无参构造器即可。

Jackson反序列化

通过debug,让我们来看这一部分的源码:
Jackson中有个BeanDeserializerBase类,该抽象类的子类BeanDeserializer包含了将字节流反序列化的一系列方法:如deserializeFromObject(JsonParser p, DeserializationContext ctxt)、deserialize(JsonParser p, DeserializationContext ctxt)。
在deserializeFromObject方法中,有这么一条判断语句:
if (this._nonStandardCreation)

  该属性_nonStandardCreation在BeanDeserializerBase类中是这样定义的:

this._nonStandardCreation = this._unwrappedPropertyHandler != null || this._valueInstantiator.canCreateUsingDelegate() ||
this._valueInstantiator.canCreateUsingArrayDelegate() || this._valueInstantiator.canCreateFromObjectWith() || !this._valueInstantiator.canCreateUsingDefault();

  我们把目光放到 this._valueInstantiator.canCreateUsingDefault()上:

public boolean canCreateUsingDefault() {
  return this._defaultCreator != null;
  }

  _defaultCreator表示了该实体类是否含有默认无参构造函数(通过反射机制获得)。

上文提到了,我们添加了新的构造函数,JVM并未给该实体类添加默认无参构造函数,因此_defaultCreator为null。回到最初的判断语句,这里的this._nonStandardCreation便是true。
当没有无参构造函数,BeanDeserializer会怎么处理呢?
它会尝试查找该类是否拥有_unwrappedPropertyHandler或者_externalTypeIdHandler,当然并没有。那么调用deserializeFromObjectUsingNonDefault方法进行deserialize。
protected Object deserializeFromObjectUsingNonDefault(JsonParser p, DeserializationContext ctxt) throws IOException {
  JsonDeserializer<Object> delegateDeser = this._delegateDeserializer();
  if (delegateDeser != null) {
  return this._valueInstantiator.createUsingDelegate(ctxt, delegateDeser.deserialize(p, ctxt));
  } else if (this._propertyBasedCreator != null) {
  return this._deserializeUsingPropertyBased(p, ctxt);
  } else {
  Class<?> raw = this._beanType.getRawClass();
  return ClassUtil.isNonStaticInnerClass(raw) ? ctxt.handleMissingInstantiator(raw, (ValueInstantiator)null, p, "can only instantiate non-static inner class by using default, no-argument constructor", new Object[0]) : ctxt.handleMissingInstantiator(raw, this.getValueInstantiator(), p, "cannot deserialize from Object value (no delegate- or property-based Creator)", new Object[0]);
  }
  }

  在该方法中它判断了两个属性:_delegateDeserializer和_propertyBasedCreator,对于这两个属性我也不是很明白。通过查阅API文档,前者表示委托反序列化Deserializer that is used if delegate-based creator is to be used for deserializing from JSON Object.,后者表示If the bean needs to be instantiated using constructor or factory method that takes one or more named properties as argument(s), this creator is used for instantiation(?)。最后判断一下是否是内部静态类,进入异常处理部分。

Spring Boot在反序列化过程中:jackson.databind.exc.InvalidDefinitionException cannot deserialize from Object value的更多相关文章

  1. Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.catalina.connector.CoyoteWriter and no properties discovered to create BeanSerializer

    一.什么是序列化In computer science, in the context of data storage, serialization is the process of transla ...

  2. jackon - com.fasterxml.jackson.databind.exc.InvalidDefinitionException && UnrecognizedPropertyException: Unrecognized field 异常

    在用jackson解析json数据是碰到的问题 1.首先是InvalidDefinitionException 测试发现可能是目标类中无无参数构造方法导致异常. 添加无参构造方法后发现前一个异常解决但 ...

  3. com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class cn.edu.

    详细信息   https://www.cnblogs.com/xuwenjin/p/8832522.html 解决办法: 在实体类上面加上注解 @JsonIgnoreProperties(value ...

  4. Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException

    实体类缺少无参构造方法,序列化对象需要无参构造方法 @NoArgsConstructor

  5. JSON parse error: Cannot deserialize instance of `int` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc

    代码程序: @PostMapping("selectById") @ResponseBody public Result selectById(@RequestBody int i ...

  6. Spring Boot 监听 Activemq 中的特定 topic ,并将数据通过 RabbitMq 发布出去

    1.Spring Boot 和 ActiveMQ .RabbitMQ 简介 最近因为公司的项目需要用到 Spring Boot , 所以自学了一下, 发现它与 Spring 相比,最大的优点就是减少了 ...

  7. spring boot 项目从配置文件中读取maven 的pom.xml 文件标签的内容。

    需求: 将pom.xml 文件中的版本号读取到配置文件并打印到日志中. 第一步: 在pom.xml 中添加以下标签. 第二步: 将version 标签的值读取到配置文件中 这里使用 @@  而不是  ...

  8. com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 异常

    分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519) 1.1.1. 前言 近期在使用ObjectMapper对象将jso ...

  9. com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ExceptionId"

    com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Exception ...

随机推荐

  1. klee源码阅读笔记1--STPBuilder类

    初始化过程中四个数据成员中的两个数据成员被初始化: 一.vc被初始化为STP提供的C调用接口函数vc_createValidityChecker(): 二.optimizeDivides被初始化为fa ...

  2. markdown中设置、调整图片尺寸

    使用百分比描述尺寸 <img src="https://img2018.cnblogs.com/blog/1122471/201902/1122471-2019022218575673 ...

  3. June 20th 2017 Week 25th Tuesday

    Care and diligence bring luck. 谨慎和勤奋,带来好运气. In my opinion, care and diligence may just gurantee us a ...

  4. February 7 2017 Week 6 Tuesday

    It does not do to dwell on dreams, and forget to live. 人不能只生活在梦里,只依靠虚幻的东西而忘记了生活. Don't forget to liv ...

  5. sql语句中where,have,on的区别

    一.where和on的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户.  在使用left jion时,on和where条件的区别如下:   1. ...

  6. arcgis server 9.3 查看地图服务时出现"No Content"错误

    问题描述: 使用ArcGIS Server Manager的Add new service功能发布一个服务.然后启动服务 用浏览器访问该服务的地址http://localhost/ArcGIS/ser ...

  7. Struts2注解开发

    Hibernate和spring框架的开发前边总结了,这次看一下流行的MVC流程框架Struts2的注解开发吧.Struts2主要解决了从JSP到Action上的流程管理,如何进行Uri和action ...

  8. PHP------数组的遍历

    echo current($attr); //取当前元素的value值 echo key($attr); //取当前元素的key next($attr); //将数组里面的指针指向下一个(向下移)pr ...

  9. 2spring注解:@Lazy,@Conditional,@import,FactoryBean接口

    大致的工程内容也来源于上一篇博文! https://www.cnblogs.com/Mrchengs/p/10108603.html 1.@Lazy懒加载 懒加载:针对单实例的 单实例bean,默认在 ...

  10. springmvc小结(下)

    1.@ModelAttribute 1.给共享的数据设置model数据设置,贴在形参上,也可以贴在方法上,设置一个model的key值 2.当controller方法返回一个对象的时候,,缺省值会把当 ...