先看症状
private Department checkDepartment(Integer id, UriComponentsBuilder ucb) {
RestTemplate template = new RestTemplate();
URI locationUri = ucb.path("/departments/")
.path(id.toString())
.build()
.toUri();
Department department = template.getForObject(locationUri, Department.class);
return department;
}
调用上述方法的处理器方法
@PatchMapping()
public ResponseEntity updateDep(@RequestBody @Validated(Department.Update.class) Department depart,
BindingResult result, UriComponentsBuilder ucb) {
if (result.hasErrors()) {
throw new DepartmentIdNullException();
}
Department department = checkDepartment(depart.getId(), ucb);
return new ResponseEntity<>(department, HttpStatus.NO_CONTENT);
}
Department类
private Integer id;
private String name;
private Date createAt;
private Date updateAt;
(忽略setter和getter方法)
Spring提供的UriComponentsBuilder免去了手动构建URL的麻烦,通过逐步指定URI中的各种组成部分(如host、端口、路径以及查询),使用它来构建UriComponents对象,可以获得适合设置给RestTemplate的URI。
在处理器方法所获得的UriComponentsBuilder中,会预先配置已知的信息如host、端口以及Servlet内容,它会从处理器方法所对应的请求中获取这些基础信息,基于这些信息,代码会通过设置路径的方法构建UriComponents其余的部分。
使用POSTMAN发送更新请求
出现了问题
"message": "JSON parse error: Can not deserialize value of type java.util.Date from String \"2018-03-14 04:48:17\": not a valid representation (error: Failed to parse Date value '2018-03-14 04:48:17': Can not parse date \"2018-03-14 04:48:17\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.util.Date from String \"2018-03-14 04:48:17\": not a valid representation (error: Failed to parse Date value '2018-03-14 04:48:17': Can not parse date \"2018-03-14 04:48:17\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS', parsing fails (leniency? null))\n at [Source: java.io.PushbackInputStream@3eff4e08; line: 1, column: 40] (through reference chain: com.management.entity.Department[\"createAt\"])",
分析解决
错误信息中表明是JSON解析错误,不能String类型的值反序列化成为Date类型
猜测:
1、Json所使用的序列化以及反序列化方式:DataBind
2、Spring提供的消息转换器(Message conversion)
检查后发现以上都不是,再认真review代码
结论得出:
应用中的某个地方自定义了一个ObjectMapper代替了默认的,那么Spring就会使用自定义的Jackson来序列化而非默认配置的。
@Bean
public ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
这就是导致Jackson反序列化出现错误的原因,去掉即可。