前言
記錄下在使用spring boot時,不小心将jackson的全局配置覆寫導緻的,正常的json格式無法解析的問題。
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
就是由于上面的配置,配置項應用于全局生效導緻的。下面我們看下具體情況。
問題還原
controller方法
@Slf4j
@RestController
@RequestMapping
public class UserClientService {
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("users")
public User addUser(@RequestBody User user) {
return user;
}
}
調用截圖

錯誤資訊
[
"java.util.LinkedHashMap",
{
"timestamp": [
"java.util.Date",
],
"status": ,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class com.zm.zhuma.user.model.po.User; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class com.zm.zhuma.user.model.po.User\n at [Source: [email protected]; line: 1, column: 1]",
"path": "/zhuma-user2/users"
}
]
備注
1. 我們可以看到controller的方法和調用時傳入的json參數格式并沒有錯誤,但是卻傳回了JSON parse error問題,粗略的翻譯下就是 不期待object對象,期待傳遞的是一個array數組。
2. 還有一個異常現象就是,spring boot預設的錯誤傳回并不是一個json的對象格式,而是一個數組這裡進行一下說明,spring boot的預設異常時傳回結果是靠{@link org.springframework.boot.autoconfigure.web.DefaultErrorAttributes}類,使用的對象是LinkedHashMap。不做處理時,傳回的預設錯誤結果應該是下面這樣:
{
"timestamp": ,
"status": ,
"error": "Not Found",
"message": "No message available",
"path": "/zhuma-user2/users/error-path"
}
Bug解決方案
最終排查到是項目中配置ObjectMapper的時候修改成了全局配置,導緻影響到了spring mvcjson格式解析(因為spring mvc預設就是使用jackson做json處理的)
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
//設定輸入時忽略JSON字元串中存在而Java對象實際沒有的屬性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//将類名稱序列化到json串中
//mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
return mapper;
}
分析
我們先來分析下enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)這個配置,配置該項後,json格式序列化時會将對象類名稱資訊也會序列化進來,反序列化時同樣也是需要 類和值的資訊,格式是一個數組(兩個長度),數組[0]存儲類的資訊,數組[1]存儲值資訊,這也印證了為什麼我們錯誤提示是 Unexpected token (START_OBJECT), expected START_ARRAY。
是以去掉改配置,就是我們最常用的json格式了。O(∩_∩)O~