使用RestAssured+Jackson反序列化时遇无构造器异常求助
解决Jackson反序列化CreateUser类的异常问题
我正在学习RestAssured框架,尝试结合Jackson与Lombok注解进行开发。已创建用于请求和响应的CreateUser模型类:
@Data @Builder @AllArgsConstructor public class CreateUser { private String job; private String id; private String name; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private Timestamp createdAt; }
我在以下方法中尝试以createUser对象作为请求体发送POST请求,并将响应字符串反序列化为CreateUser对象返回:
public static CreateUser createUser(String name, String job) throws IOException { CreateUser createUser = CreateUser.builder() .name(name) .job(job) .build(); String jsonResponse = given() .when() .baseUri(baseUri) .contentType(ContentType.JSON) .body(createUser) .post("/users") .body() .asString(); ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(jsonResponse, CreateUser.class); }
运行时出现如下异常:
Cannot construct instance of `test.model.CreateUser` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)"{"job":"leader","id":"398","name":"morpheus","createdAt":"2023-07-10T18:04:35.486Z"}"; line: 1, column: 2] com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `test.model.CreateUser` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)"{"job":"leader","id":"398","name":"morpheus","createdAt":"2023-07-10T18:04:35.486Z"}"; line: 1, column: 2] at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452) at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3005)
解决方法
异常核心原因是Jackson找不到CreateUser类的合适构造方法完成反序列化,以下是三种可行解决方案:
方法1:添加无参构造函数
在CreateUser类上添加@NoArgsConstructor注解,让Lombok生成无参构造函数,Jackson默认会通过无参构造创建对象再赋值:
@Data @Builder @AllArgsConstructor @NoArgsConstructor // 添加该注解 public class CreateUser { private String job; private String id; private String name; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private Timestamp createdAt; }
方法2:启用Jackson的Lombok模块支持
引入jackson-datatype-lombok依赖,让Jackson识别Lombok生成的Builder:
- 添加Maven依赖(版本需与项目中Jackson版本一致):
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-lombok</artifactId> <version>你的Jackson版本号</version> </dependency>
- 配置ObjectMapper注册Lombok模块:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new LombokModule()); return mapper.readValue(jsonResponse, CreateUser.class);
方法3:给全参构造函数添加Jackson注解
通过@JsonCreator和@JsonProperty让Jackson直接使用全参构造函数实例化对象:
@Data @Builder @AllArgsConstructor(onConstructor = @__(@JsonCreator)) public class CreateUser { @JsonProperty("job") private String job; @JsonProperty("id") private String id; @JsonProperty("name") private String name; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") @JsonProperty("createdAt") private Timestamp createdAt; }
内容的提问来源于stack exchange,提问作者anusree v
相关产品推荐
相关产品推荐

