你以為你以為的就是你以為的嗎?記一次伺服器點對點通知的聯調過程

来源:https://www.cnblogs.com/buguge/archive/2019/12/13/12035854.html
-Advertisement-
Play Games

公司兩個系統。 我們的A系統要給B系統上送業務簽約單申請。B系統接收數據後,非同步處理,簽約完成會主動發送通知給我們的A系統。 介面文檔里說明瞭,通過http協議的post請求來發送非同步通知,報文是json格式字元串。But,But,But, ...


公司兩個系統。

我們的A系統要給B系統上送業務簽約單申請。B系統接收數據後,非同步處理,簽約完成會主動發送通知給我們的A系統。

介面文檔里說明瞭,通過http協議的post請求來發送非同步通知,報文是json格式字元串。

 

我們A系統定義restful的http介面。

【題外話】@RequestBody註解:@RequestBody接收的參數是來自requestBody中,即請求體。適用於http post請求。請求端通過HttpEntity傳遞參數,併在請求頭中聲明數據的類型Content-Type,SpringMVC通過使用 HandlerAdapter 配置的HttpMessageConverters來解析HttpEntity中的數據,然後綁定到相應的bean上。

@RestController
@Slf4j
public class TaxNotifyController {

    @Reference
    private TaxNotifyService taxNotifyService;

    /**
     *
     * @param notifyVO
     * @return
     */
    @PostMapping("/ayncNotify")
    @UnAuthToken
    public String ayncNotify(@RequestBody NotifyVO notifyVO){
        log.info("收到回調----非同步回調----非同步通知----回調通知:{}", JSON.toJSONString(notifyVO));
        String respText = taxNotifyService.ayncNotify(notifyVO);
        log.info("回調----非同步回調----非同步通知----回調通知 回寫內容:{}",respText);
        return respText;
    }
}

 

QA在測試過程中,發現我方一直收不到對方的回調。有對方日誌截圖為證。

 

查看我們A系統的log。並沒有發現“收到回調----非同步回調----非同步通知----回調通知”這樣的log。

 

難道是B系統到我們A系統的網路不通?雙方都是測試環境呀!還是去找運維確認吧。

[root@localhost logs]# curl http://192.168.40.84:8802/ent-boot/ayncNotify
{"code":"ERROR","message":"Request method 'GET' not supported"}

 

因為需要POST,所以curl接收到這個錯誤。但至少證明這2個系統間的網路是沒問題的。

 

再次確認我方log。發現蛛絲馬跡:

2019-12-13 11:07:01.894 [http-nio-8802-exec-9] INFO  com.emaxcard.car.filter.CrosXssFilter:40 - 
CrosXssFilter.......orignal url:/ent-boot/ayncNotify,ParameterMap:{} 2019-12-13 11:07:01.895 [http-nio-8802-exec-9] WARN o.s.w.s.m.support.DefaultHandlerExceptionResolver:197 -
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/xml;charset=UTF-8' not supported] 2019-12-13 11:07:01.895 [http-nio-8802-exec-9] INFO com.emaxcard.car.filter.CrosXssFilter:44 -
CrosXssFilter..........doFilter url:/ent-boot/ayncNotify,ParameterMap:{}

 

莫非,對方給的content-type是text/xml??

 

找B系統的開發同學,經查代碼里HttpUtil,果然,指定的content-type是text/xml。 如下圖。我們知道,springmvc預設接收數據的格式是json方式序列化的。你指定成xml格式,顯然springmvc在反序列化成NotifyVO對象時會拋出異常。自然,就不會執行這個action方法了,所以,我們沒看到那條“收到回調----非同步回調----非同步通知----回調通知”log。

【題外話】關於springmvc的messageconverter設置,可以查看spirng-web.jar里的RestTemplate.java源碼。

Line122:jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);

 

接著說,我們讓這位開發同學改成 application/json 後,問題得以解決。

 

 

ButButBut,下午,QA在測試付款單的回調的時候,同樣的問題又出現了,我們接收不到請求報文。一看log,又是text/xml搞的鬼。B系統的這個付款回調是另一個同學開發的。考慮到目前已經有外部商戶接入B系統,他們不准備改了。

不改就不改吧,B系統他們不改,只好我們A系統改了。話說回來,即便他們現在不改,日後有其他商戶對接聯調時,也難免會出現類似的問題。那,就是以後的事兒了。

我們怎麼改呢?那就不直接從RequestBody里接收NotfiyVO對象了,改成接收String字元串。然後,在方法里來做判斷和反序列化。改後的代碼為:

    @PostMapping("/ayncNotify")
    @UnAuthToken
    public String ayncNotify(@RequestBody String notifyStr){
        log.info("收到回調----非同步回調----非同步通知----回調通知:{}", notifyStr);
        if(StringUtils.isBlank(notifyStr)){
            log.info("回調通知為空");
            return "ERROR-回調通知請求參數為空";
        }
        NotifyVO notifyVO = JSON.parseObject(notifyStr,NotifyVO.class);
        log.info("回調轉換NotifyVo:{}",notifyVO);
        String respText = taxNotifyService.ayncNotify(notifyVO);
        log.info("回調----非同步回調----非同步通知----回調通知 回寫內容:{}",respText);
        return respText;
    }

 

 

THE END.

下午得知,一同學在對接付款介面時,當付款介面返回受理失敗時,他把付款單的付款結果改成了失敗。這可要不得呀!付款結果一定要通過付款查詢介面來查。查詢返回付款成功,則付款成功;查詢返回付款失敗,則付款失敗;對於查詢到的其他結果,保守起見,都視為付款中即可,然後由人工來干預。技術人員千萬別自作主張,把某些不明確的結果定為付款失敗。萬一齣現重覆付款,那就尷尬了。我在2016年那時剛開始做聚合支付時,是有這樣的慘痛經歷的。

 

 ☞ Stay Hungry,Stay Foolish. 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有時候會遇到這種情況,某些屬性指向限制在特定範圍內,當別人調用的時候,只能賦值在這特定範圍內的值。這樣的情況有哪些呢?比如有一個屬性是用來放年齡的,那麼這個年齡就不能被設置為負數。還有人的性別隻有男跟女兩種選擇,別來一個雌雄同體。在這樣的情況下,就會用到封裝跟隱藏。 信息的封裝和隱藏 Java中通過 ...
  • 關閉防火牆,設置虛擬機和本機在同一網段,還是ping不同 解決方法:在VMware中點擊 編輯 >虛擬網路編輯器 >更改設置 >還原預設設置 然後重新配置虛擬機和本機在同一網段,關閉VMnet1,啟動VMnet8 ...
  • 軟體包:類似於電腦的文件管理方式,主要解決同名文件。 包幫助管理大型軟體系統:將語義類似的類組織到包中;解決類命名衝突的問題。 包可以包含類和子包。 關鍵字——package package語句作為Java源文件的第一條語句,指明該文件中定義的類所在的包。若預設該語句,則指定為無名包。 格式:pac ...
  • 目錄結構: —|controller —|Home.php —|model —|view —|welcome.php —|index.php 基本原理: 首頁 index.php 通過獲得地址欄中的路由名稱獲得對應控制器以及控制的方法名,通過require引入到index.php首頁中。通過引入的對 ...
  • 重載的概念 在同一個類中,允許存在一個以上的同名的方法,只要它們的參數個數或者參數類型不同的話就行。 重載的特點 與返回值類型無關,只看參數列表,且參數列表必須不同。(參數個數、參數類型、參數排列順序) 理解:就只要參數列表不要完全一樣就行。和返回值類型無關。 方法的可變個數的形參 在遇到不知道要給 ...
  • 前言 只有光頭才能變強。 文本已收錄至我的GitHub精選文章,歡迎Star : "https://github.com/ZhongFuCheng3y/3y" 相信大家對他也不陌生了,前後端交互中常常就以 來進行 數據交換 。而有的時候,我們也會將 直接保存在資料庫中。 可能就有人不太理解,為什麼要 ...
  • 昨天有使用soap傳輸數據到Webservice,其中字元串類型的都已經傳輸成功,但是有幾個參數傳輸失敗,java伺服器端收到的空值。 因為我是php的,然後接收端是java製作的,其中有幾個參數是list數組類型的,我剛開始將php的數組傳過去,服務端接收到的是空,然後再使用json格式還是不行。 ...
  • 第一次寫博客,本文主要源於圖像處理大作業,不足之處,還望指正。 1. Introduction (5%) The task of the project is to find the dial-code switch in the figure below and calibrate the rec ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...