異常解決篇:Spring Boot預設錯誤返回格式變成陣列@RequestBody無法解析Json格式
前言
記錄下在使用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",
1520232987376
],
"status": 400,
"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": 1520236497590,
"status": 404,
"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~
相關推薦
異常解決篇:Spring Boot預設錯誤返回格式變成陣列@RequestBody無法解析Json格式
前言 記錄下在使用spring boot時,不小心將jackson的全域性配置覆蓋導致的,正常的json格式無法解析的問題。 ObjectMapper mapper = new ObjectMapper(); mapper
輕輕鬆鬆學習SpringBoot2:第五篇:Spring Boot獲取properties檔案中的漢字亂碼解決
上篇文章,我們雖然獲取到了配置檔案中的值,但是我們發現中文是亂碼這可不是我們想要的,那麼該如何解決呢1)通過工具進行設定:在IntelliJ IDEA中依次點選File -> Settings -> Editor -> File Encodings 其他工具
SpringBoot自學教程 | 第四篇:Spring Boot整合mybatis
整合 com 字段 apach param pack image ice rac 引入依賴 1:在pom文件引入mybatis-spring-boot-starter的依賴: 1 <dependency> 2 <groupId>
SpringBoot非官方教程 | 第二篇:Spring Boot配置檔案詳解
springboot採納了建立生產就緒Spring應用程式的觀點。 Spring Boot優先於配置的慣例,旨在讓您儘快啟動和執行。在一般情況下,我們不需要做太多的配置就能夠讓spring boot正常執行。在一些特殊的情況下,我們需要做修改一些配置,或者需要有自己的配置屬性。 當我們
SpringBoot學習第二篇:Spring Boot配置檔案詳解
原文首發於:https://www.fangzhipeng.com/springboot/2017/07/11/springboot2-config-file/ 本文出自方誌朋的部落格 springboot採納了建立生產就緒Spring應用程式的觀點。 Spring Boot優先於配置的慣例,旨
第九篇:Spring Boot整合RabbitMQ
RabbitMQ是一個開源的訊息代理和佇列伺服器,用來通過普通協議在完全不同的應用之間共享資料,或者簡單地將作業佇列以便讓分散式伺服器進行處理。訊息佇列使用訊息將應用程式連線起來,這些訊息通過像RabbitMQ這樣的訊息代理伺服器在應用程式之間路由。這篇文章將帶你瞭解怎麼整合Rabbit
第八篇:Spring Boot使用Redis實現訊息佇列
目前常用的訊息佇列大概有三種類型,RabbitMQ等AMQP系列, Kafka, Redis等key-value系列,它們的使用場景分別是: 1.RabbitMQ:相對重量級高併發的情況,比如資料的非同步處理,任務的序列執行等. 2.Kafka:基於Pull的模式來處理,具體
第七篇:Spring Boot整合Spring Cache
為了提高效能,減少資料庫的壓力,使用快取是非常好的手段之一。因此本文講解 Spring Boot 如何整合快取管理。 宣告式快取 Spring 定義 CacheManager 和 Cache 介面用來統一不同的快取技術。例如 JCache、 EhCache、 Hazelcast、
第六篇:Spring Boot整合Swagger2構建RESTful API文件
由於Spring Boot有快速開發、便捷部署等特性,所以很大一部分Spring Boot的使用者會用來構建RESTfulAPI。而我們構建RESTfulAPI的目的通常都是由於多終端的原因,這些終端會共用很多底層業務邏輯,因此我們會抽象出這樣一層來同時服務於多個移動端或者Web前端。
第五篇:Spring Boot整合Redis
Redis 是一個高效能的key-value資料庫,它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set --有序集合)和hash(雜湊型別)。使用redis作為快取技術方案,主要是因為Redis快取技
第四篇:Spring Boot開啟宣告式事務
Spring支援宣告式事務,即使用註解來選擇需要使用事務的方法,它使用@Transactional註解在方法上表明該方法需要事務支援。當然,Spring Boot開啟事務也只需要一個註解@Transactional 就可以了。 準備階段 在pom檔案中引入mybatis啟動依賴:
第三篇:Spring Boot整合MyBatis
本文主要講解如何在Spring Boot下整合MyBatis並訪問資料庫。MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。(如不瞭解點選前往) 環境依賴 修改 POM 檔案,新增mybatis-spring-boot-starter依賴。值得注
第二篇:Spring Boot配置檔案詳解
Spring Boot採納了建立生產就緒Spring應用程式的觀點。 Spring Boot優先於配置的慣例,旨在讓您儘快啟動和執行。在一般情況下,我們不需要做太多的配置就能夠讓Spring Boot正常執行。在一些特殊的情況下,我們需要做一些配置修改,或者配置自定義屬性。 自定義屬
轉載:SpringBoot非官方教程 | 第二篇:Spring Boot配置檔案詳解
springboot採納了建立生產就緒Spring應用程式的觀點。 Spring Boot優先於配置的慣例,旨在讓您儘快啟動和執行。在一般情況下,我們不需要做太多的配置就能夠讓spring boot正常執行。在一些特殊的情況下,我們需要做修改一些配置,或者需要
輕輕鬆鬆學習SpringBoot2:第二十五篇: Spring Boot和Mongodb整合(完整版)
今天主要講的是Spring Boot和Mongodb整合我們先來回顧一下前面章節的相關內容前面我們講了SpringBoot和mysql整合,並且講了操作資料庫的幾種方式自動生成表資料庫操作操作篇回到正題,mongodb的安裝在這就不累述了,win版本的去官網下載,然後一直下一
第十四篇:Spring Boot+MyBatis配置多資料來源
說起多資料來源,一般都來用來解決主從模式或者業務比較複雜需要連線不同的分庫來支援業務。本篇文章主要講解後者的模式,利用AOP動態切換來達到專案訪問不同資料來源。 構架工程 建立一個springboot工程,在其pom檔案加入: <dependency> &
第十三篇:Spring Boot之郵件服務
傳送郵件應該是網站的必備功能之一,什麼註冊驗證,忘記密碼或者是給使用者傳送營銷資訊。最早期的時候我們會使用JavaMail的相關API來編寫傳送郵件的相關程式碼,後來Spring推出了JavaMailSender更加簡化了郵件傳送的過程,再之後Spring Boot對此進行了封裝就有了現
第十二篇:Spring Boot之使用Spring RestTemplate訪問Rest服務
RestTemplate是Spring3.0後開始提供的用於訪問 Rest 服務的輕量級客戶端,相較於傳統的HttpURLConnection、Apache HttpClient、OkHttp等框架,RestTemplate大大簡化了發起HTTP請求以及處理響應的過程。這篇文章主要介紹怎
第十一篇:Spring Boot之Scheduling Tasks定時任務
幾乎大部分的應用都會有定時執行任務的需求。使用Spring Boot的Scheduling Tasks能夠提高您的開發效率。這篇文章將介紹怎麼通過Spring Boot去做排程任務。 構建工程 建立一個Springboot工程,在它的程式入口加上@EnableScheduling
第十篇:Spring Boot整合WebSocket
WebSocket是通過一個Socket來實現雙工非同步通訊的。直接使用WebSocket或者SockJS協議顯得特別繁瑣。使用它的子協議STOMP,它是一個更高級別的協議,STOMP協議使用一個基於幀格式來定義訊息,與HTTP的Request和Response類似。 環境依賴