我今天在使用Ribbon 遠程調用的時候spring
消費者去消費服務端所提供的服務,在使用Post請求中的PostForEntity傳遞參數的時候,我是這樣寫的網絡
Ribbon 消費端:app
User 是一個 Pojo 對象,代碼以下:ide
public class User { private Integer id; private String name; public User(Integer id, String name) { this.id = id; this.name = name; } get... and set ... }
Ribbon 服務端:函數
就是一個很簡單的Ribbon 遠程調用的一個操做,報以下錯誤:ui
跟入源碼:this
而後就不明覺厲了,第一開始比較煩躁,一直覺得是消費端的問題,由於錯誤是從消費服務端報出來的。後來通過冷靜發現,上述代碼是在處理服務端響應的時候報出來的,應該仍是服務端報錯來的錯誤。google
2019-04-14 13:56:27.183 WARN 3500 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not construct instance of com.service.provider.pojo.User: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.service.provider.pojo.User: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: java.io.PushbackInputStream@25979c35; line: 1, column: 2]
代碼並不能看懂什麼意思,求助google,從stackoverflow上找到了問題的答案:3d
沒有加默認的構造函數?????? 這是什麼鬼? 默認的構造函數和JSON解析有什麼關係?
可是可以解決問題了,我檢查了一遍我一直覺得個人值沒有傳遞過去,但我看已經傳遞到服務端了(避免了一個白癡問題)。
====================================華麗的分割線====================================
事實印證了我是個菜比。
事情是這樣的
Ribbon的消費者向服務者提供的數據轉換是要把對象轉換爲二進制數據,這個過程稱之爲序列化
而服務端收到二進制的數據再轉換爲對應的對象,這個過程稱之爲反序列化
序列化會把對象保存在磁盤中,或容許直接在網絡中直接傳輸對象
反序列化就是收到二進制的數據,再轉換爲對應的對象。
而實現對象序列化的方法有兩種:
1. 實現序列化接口
2. 提供無參構造函數
而上面報錯的緣由就是由於沒有提供默認的構造函數或者實現序列化接口!!!!!
添加無參構造函數
解決問題一,再上面的Pojo類上添加默認的構造函數
public class User { private Integer id; private String name; public User(){} public User(Integer id, String name) { this.id = id; this.name = name; } get and set... }
再次調用接口,客戶端可以打印出來對應的日誌