Kubernetes官方java客戶端之二:序列化和反序列化問題

      網友投稿 688 2022-05-30

      歡迎訪問我的GitHub

      https://github.com/zq2599/blog_demos

      問題場景

      本文是《Kubernetes官方Java客戶端》的第二篇,在進入編碼實戰章節之前,有個問題需要大家有足夠的了解,避免在后面的實戰中耗費精力處理此類問題,來看看究竟是什么問題:

      SpringBoot是常用的應用框架,《Kubernetes官方java客戶端》系列的應用都是基于SpringBoot-2.3.1版本的;

      下圖是SpringBoot-2.3.1.RELEASE的官方文檔,紅框表明默認的JSON處理庫是Jackson:

      看到這里您是否有種不祥預感:K8S官方java客戶端是谷歌的,涉及到JSON處理時會不會首選自家的Gson?

      V1HTTPGetAction.java

      是java客戶端中常用到的數據結構,用來封裝http請求相關的參數,來看看其源碼,如下圖,果然用上了Gson的注解:

      上圖提到的

      IntOrString

      類要重點關注,用處廣泛,打開其源碼如下圖,請記下紅框2中的代碼,后面提到的問題就來源于此:

      小結:SpringBoot默認的JSON處理類是Jackson,K8S官方java客戶端內的Bean在涉及到JSON相關的序列化和反序列化處理時,使用了Gson注解,因此上述Bean實例在SpringBoot中涉及到JSON處理時,可能會有問題(這時只能說可能),例如RestController返回對象,會被Jackson轉為JSON;

      復現問題

      這里用一個SpringBoot工程來演示此問題(該工程名為OutsideclusterApplication,下一篇文章會詳細說明),如下代碼是個http接口響應,可見V1PodList實例作為接口返回時,會被SpringBoot用Jackson轉為JSON返回給前端:

      @RequestMapping(value = "/hello") public V1PodList hello() throws Exception { // 存放K8S的config文件的全路徑 String kubeConfigPath = "/Users/zhaoqin/temp/202007/05/config"; // 以config作為入參創建的client對象,可以訪問到K8S的API Server ApiClient client = ClientBuilder .kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))) .build(); Configuration.setDefaultApiClient(client); CoreV1Api api = new CoreV1Api(); // 調用客戶端API取得所有pod信息 V1PodList v1PodList = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null); return v1PodList; }

      上述代碼運行起來,在瀏覽器訪問該接口時,控制臺拋出以下錯誤,IntOrString.getStrValue方法,就是前面咱們看過的那段,IntOrString中實際上保存的是int數據,但是Jackson執行了其

      getStrValue

      方法:

      至于為什么Jackson會執行getStrValue方法,篇幅原因就不在此展開了,簡單提一下,在java客戶端的BeanPropertyWriter類中,選擇方法的邏輯如下圖,紅框中展示了判定邏輯,此處getStrValue方法命中了該邏輯,如果您嘗試用在紅框處打上斷點觀察,會發現有很多方法都符合此條件:

      解決問題的思路

      我這里,解決問題的思路有兩個:

      讓Jackson在序列化的時候,能夠調用正確的方法,以IntOrString為例,如果此時內部保存int型數據,就應該執行其getIntValue方法即可;

      Bean中使用了Gson注釋,就是打算用Gson來處理序列化和反序列化操作的,因此序列化和反序列化的地方都改用Gson處理;

      Kubernetes官方java客戶端之二:序列化和反序列化問題

      上述兩個思路,我選擇了第二種,畢竟第一種太難了…

      解決問題

      問題解決起來并不難,先看SpringBoot-2.3.1.RELEASE官方文檔:

      結合官方文檔,我們要做兩件事情:

      首先,classpath中有Gson,這個已經有了,因為K8S官方java客戶端會依賴Gson;

      其次,classpath中不要出現Jackson,為了達到這個目的我們需要做以下操作,排除spring-boot-starter-web的依賴(為什么不直接排除jackson的庫呢?您可以執行mvn dependency:tree命令細看依賴樹,會發現對jackson的依賴并非單一關系):

      org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-json

      建議您執行mvn dependency:tree命令細看整個項目的依賴樹,確保jackson依賴已經全部去掉;

      再次運行上述項目,如下圖,服務端不再報錯,頁面上返回數據正常:

      使用Jackson的場景

      上述方式雖然可行,但并非所有項目都能堅持使用Gson而放棄Jackson,對于使用Jackson的項目,請避免Jackson參與K8S官方java客戶端bean的序列化和反序列化操作,以上面出現的Controller代碼為例,不要直接將V1PodList實例返回,您可以選擇先用Gson序列化成JSON字符串,再返回字符串給前端,也可以自己定義VO對象,將V1PodList實例轉成VO對象再返回;

      至此,使用K8S官方java客戶端之前要注意的問題已經弄明白了,接下來的進入精彩的實戰章節吧,一起體驗kubernetes官方為java程序員精心準備的工具;

      Java Kubernetes

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:軟件需求管理
      下一篇:通過一個簡單的例子,了解 Cypress 的運行原理
      相關文章
      亚洲人色大成年网站在线观看| 亚洲AV电影院在线观看| 久久久国产精品亚洲一区| 亚洲色婷婷六月亚洲婷婷6月| 色偷偷亚洲第一综合| 亚洲综合偷自成人网第页色| 亚洲一区二区三区高清视频| 亚洲国产精品综合福利专区| 亚洲欧洲视频在线观看| 亚洲毛片在线免费观看| 亚洲欧洲精品一区二区三区| 亚洲春色另类小说| 亚洲国产精品午夜电影| 亚洲人成日本在线观看| 亚洲丰满熟女一区二区v| 亚洲不卡中文字幕| 亚洲一区精彩视频| 亚洲综合在线一区二区三区| 亚洲AV永久无码精品网站在线观看 | 小说区亚洲自拍另类| 色偷偷亚洲第一综合| 亚洲国产精品一区二区第一页免| 亚洲色偷偷狠狠综合网| 自拍偷自拍亚洲精品第1页| 亚洲日本va在线视频观看| 亚洲av鲁丝一区二区三区| 久久青青草原亚洲av无码app| 亚洲综合一区二区精品久久| 亚洲国产精品乱码在线观看97| 亚洲va在线va天堂va手机| 91在线亚洲综合在线| 亚洲AV无码一区二区三区网址 | 亚洲另类无码专区首页| mm1313亚洲国产精品无码试看 | 亚洲一级毛片中文字幕| 亚洲熟妇无码AV| 另类专区另类专区亚洲| 国产亚洲精品AA片在线观看不加载 | 亚洲精品无码久久久久秋霞| 天天综合亚洲色在线精品| 狠狠色婷婷狠狠狠亚洲综合|