StarringV6平臺常見問題處理

背景

Starring V6平臺作爲金融業前置系統和ESB實施的行業標杆,但是在實際應用過程中,可能會遇到一些非標準化的第三方系統,平臺原有的標準化處理無法適配特殊情況,這個時候需要自行做個性化處理。本文主要說一些常見的需要個性化處理的問題。



常見問題

A、如何判斷使用平臺接出點還是CLI端連接第三方?

平臺接出點僅適用於對方請求返回報文均爲HTTP標準JSON報文,標準JSON報文的檢驗可以去百度搜索JSON格式化、或者使用本地JSON格式化工具HiJSON來檢驗,一旦對方返回報文JSON裏面的某個字段類型不確定,儘量使用Cli端處理,避免後期改造起來有重複工作量。


B、如何處理對方返回非標準報文成標準格式?適用於任何報文改造,想怎麼玩就怎麼玩

根據平臺定義的數據對象和報文格式,對方返回的報文經常會改變某一個字段的類型,比如當某字段爲空時,第三方系統返回該字段爲空字符串,當該字段有內容時,對方又返回了數組。

在平臺中,我們定義的這個字段是數組,此時需要我們對返回報文進行轉換處理,將對方返回的該字段爲空時的空字符串替換成空數組格式。

1、在平臺引入的Bean對象裏面加上如下方法。

public void formatFMT() {
    String logFile = SUtil.getLogFile();
    TrcLog.info(logFile, "解析接收字符串開始");
    DtaInfo dtaInfo = DtaInfo.getInstance();
    byte[] bytes = (byte[]) EPOper.get(dtaInfo.getTpId(), SysDef.GDTA_FORMAT + 0 + SysDef.FORMAT_ITEMDATA);
    String recData = null;
    try {
        recData = new String(bytes, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    TrcLog.info(logFile, "接收原始數據:" + recData);

    TrcLog.info(logFile, "對原始數據進行處理");  //TODO 此處可以添加對String字符串的自定義處理,比如原始數據驗籤、解密、字符替換、內容完善、格式調整等等操作
    TrcLog.info(logFile, "原始數據處理後:" + recData);

    EPOper.put(dtaInfo.getTpId(), SysDef.GDTA_FORMAT + 0 + SysDef.FORMAT_ITEMDATA, recData);
    EPOper.put(dtaInfo.getTpId(), SysDef.GDTA_FORMAT + 0 + SysDef.FORMAT_LENGTH, recData.getBytes().length);
    TrcLog.info(logFile, "打印數據池:" + EPOper.epToJSON(DtaInfo.getInstance().getTpId(), "UTF-8"));
    TrcLog.info(logFile, "解析接收字符串結束");
}

2、此時代碼已經備好了,該在何處享用呢?

如果是Cli端的返回,是在CLI端的 解析交易報文前事件,如下圖:

image

如果是在接出點,則是在接出點的 報文接收前事件 調用上面的代碼即可,調用方法相同。

以上情況適用於對方系統所有交易返回報文的共性問題,都需要統一處理,如果只有部分交易報文需要特殊處理,可以將處理方法加在具體交易的事件上,避免造成對其他交易的影響。

如下:

image


C、查看平臺內部對象的值,以及在內部流轉過程中數據賦值情況。

平臺默認只輸出了部分日誌,一旦自己開發過程中步驟出錯,導致交易內部報錯,無法查看詳細內部賦值過程,經常出現接入點接收報文有值,經過ALA調用接出點/CLI端出去就沒值了。

一般是數據映射問題,此時需要看平臺內部對象是否賦值成功,通過日誌無法查看,可以自定義平臺方法,打印交易數據池,會將請求對象、響應對象、平臺對象全部輸出到日誌,方便排查問題。

1、在平臺引入的Bean對象裏面加上如下方法。代碼如下:

 public void printPool() {
        String logFile = SUtil.getLogFile();
        TrcLog.log(logFile, EPOper.epToJSON(DtaInfo.getInstance().getTpId(), SysDef.FILE_ENCODING));
    }

同樣,在平臺引入的Bean對象裏面加上方法,在DTA或者ALA或者交易的事件上調用該方法即可輸出平臺交易過程中全部對象內容。


D、平臺請求報文頭賦值處理。

最近幾年隨着互聯網模式的興起,很多銀行也上了雲平臺,部分系統都是採用互聯網交互模式。特別是對第三方外部系統的交互,互聯網模式下需要對交易的請求頭Header進行處理和校驗。

平臺默認只對通訊協議的請求頭做了處理,比如 Content-Type、Connection、accept、host 等等通用請求頭賦值,如果第三方需要使用特殊的請求頭字段,則需要個性化處理。

比如第三方需要在請求頭裏面加上X_ACCOUNT_KEY、X_NONCE、X_CREATED、X_SIGN等內容。

1、在平臺引入的Bean對象裏面加上如下方法。處理代碼如下:

 public void tx() {

        String logFile = SUtil.getLogFile();
        String x_account_key = "just for test";
        String accountSecret = "just for test";

        long created = System.currentTimeMillis();
        String nonce = UUID.randomUUID().toString();
        String sign = OpenSDKKC.signCredential(x_account_key, accountSecret, nonce, created);
        TrcLog.log(logFile, "計算sign:" + sign);

        Map<String, String> heads = new HashMap<>();
        heads.put(OpenSDKKC.X_ACCOUNT_KEY, x_account_key);
        heads.put(OpenSDKKC.X_NONCE, nonce);
        heads.put(OpenSDKKC.X_CREATED, String.valueOf(created));
        heads.put(OpenSDKKC.X_SIGN, sign);
        heads.put("accept", "application/json");
        heads.put("Content-Type", "application/json");
        heads.put("Connection", "keep-alive");

        DtaInfo dtaInfo = DtaInfo.getInstance();
        int i = 0;
        for (Map.Entry<String, String> entry : heads.entrySet()) {
            EPOper.put(dtaInfo.getTpId(), "__HTTP_HEADER[0].__KEY[" + i + "]", entry.getKey());
            EPOper.put(dtaInfo.getTpId(), "__HTTP_HEADER[0].__VALUE[" + i + "]", entry.getValue());
            i++;
            TrcLog.log(logFile, "key:" + entry.getKey() + " value:" + entry.getValue());
        }

    }

以上是對請求頭的賦值處理,只需要替換 heads.put(“”,””)裏面的內容即可完成請求Header頭的處理,固定請求頭直接寫死,需要計算的頭處理則自定義計算後賦值。

2、在定製的接出點,調用該方法即可完成對請求頭的Header賦值。

image

3、輸出結果示例如下:

image

4、很多時候內部系統調用時,帶了它自身的請求頭,比如上圖中的c-business-id、c-app-id,這種第三方根本不care的請求頭信息,如果對方不報錯,則可以不用理會,偶爾對方會因爲多出一些Header頭信息導致調用交易出錯。

我們則需要去掉內部系統請求時帶的Header頭信息,只賦值第三方系統需要的Header頭,則需要增加一行刪除Header頭信息的代碼,上述代碼修改如下:

 public void tx() {

        String logFile = SUtil.getLogFile();
        String x_account_key = "just for test";
        String accountSecret = "just for test";

        long created = System.currentTimeMillis();
        String nonce = UUID.randomUUID().toString();
        String sign = OpenSDKKC.signCredential(x_account_key, accountSecret, nonce, created);
        TrcLog.log(logFile, "計算sign:" + sign);

        // 此代碼爲清除請求Header頭信息,如不需要則屏蔽
        com.adtec.starring.datapool.HttpHeaderOper.deleteAll();
        Map<String, String> heads = new HashMap<>();
        heads.put(OpenSDKKC.X_ACCOUNT_KEY, x_account_key);
        heads.put(OpenSDKKC.X_NONCE, nonce);
        heads.put(OpenSDKKC.X_CREATED, String.valueOf(created));
        heads.put(OpenSDKKC.X_SIGN, sign);
        heads.put("accept", "application/json");
        heads.put("Content-Type", "application/json");
        heads.put("Connection", "keep-alive");

        DtaInfo dtaInfo = DtaInfo.getInstance();
        int i = 0;
        for (Map.Entry<String, String> entry : heads.entrySet()) {
            EPOper.put(dtaInfo.getTpId(), "__HTTP_HEADER[0].__KEY[" + i + "]", entry.getKey());
            EPOper.put(dtaInfo.getTpId(), "__HTTP_HEADER[0].__VALUE[" + i + "]", entry.getValue());
            i++;
            TrcLog.log(logFile, "key:" + entry.getKey() + " value:" + entry.getValue());
        }

    }


E、將JSON字符串轉換成平臺對象處理。

1、在一些特殊情況下,和第三方的通訊這一端,並沒有使用平臺的接出點或者調用CLI端組報文,比如form-data形式的文件上傳,平臺的支持性不是很好,需在交易的ALA邏輯處理裏自定義代碼來完成交易,或者第三方平臺使用的是自己的SDK包,並不是以接口的形式來交互,這種第三方代碼調用後,返回報文會以JSON字符串形式接收,收到後需要映射到平臺定製的對象上去,不做映射處理,平臺的對象是沒有值的。

2、在接收到返回JSON字符串之後,需要自定義代碼來處理返回信息。

比如交易 IWS0006006 的響應對象是:UPLOADONETHINGFILE_RES

對象裏面的字段和第三方返回結構字段一致:

image

代碼調用第三方交易後成功收到返回JSON字符串內容:

{
    "fpath": "",
    "message": "",
    "success": "true"
}

我們則要把第三方返回JSON字符串賦值到平臺對象UPLOADONETHINGFILE_RES,代碼如下:

String result = "第三方返回JSON字符串內容,如上圖所示";
result = "{\"UPLOADONETHINGFILE_RES\":" + result + "}";
TrcLog.info(logFile, "響應數據 = " + result);
EPOper.jsonToEP(dtaInfo.getTpId(), result); //平臺此處代碼賦值

// 此處就可以從平臺對象取值
CompSDO sdo = EPOper.getCompSDO(dtaInfo.getTpId(), "UPLOADONETHINGFILE_RES");
String success = (String) sdo.getValue("success");
String message = (String) sdo.getValue("message");
String fpath = (String) sdo.getValue("fpath");


F、


G、


H、


J、


K、


L、爲什麼需要自定義平臺通訊類

隨着公司不斷拓展業務範疇,對接互聯網模式的概率越來越普遍,外部互聯網公司開發的系統接口模式繁多,一家系統的接口可能就包含有GET(拼接URL、restful風格、restful風格key=value傳參等)/POST(拼接URL、表單提交、JSON報文格式)/文件流傳輸/文件流帶報文體模式form-data等各種亂七八糟的情況,可能部分公司對於接口標準沒有明確定義,而且多爲前後端未分離的系統,對接的第三方系統一般都已上線,臨時讓人修改接口顯然也是不合適的,如果碰到配合的公司你說改,對方就改了,那算你運氣好。不然的話你想想平臺應該怎麼定架構,一個第三方系統,對於我們來說一般統一走一個CLI端或者接出點,因爲平臺默認一個CLI端和接出點只能用一種協議。

第三方調用示例如下:

常規GET http://www.xxx.xxxx.com/pzInter/edu?PARAMS=MDEyMzExNzg5MjE3MzYyOQ==&FLAG=1
常規GET https://www.xxx.xxxx.com/pzInter/edu?PARAMS=MDEyMzExNzg5MjE3MzYyOQ==&FLAG=1
異常restf風格GET http://www.xxx.xxxx.com/eduInterface/edu/v1/xkcj/kshId=MTkwMTAyMDAxMDE=/pwdId=MTIwMDEz/23123/yzm=232323
標準restful風格GET http://www.xxx.xxxx.com/instancecode/reqcode/2994
拼接URL風格POST http://www.xxx.xxxx.com/search/crjqueryn?sfzh=43018123233902265519&ywbh=4301442234101005747
表單提交POST 
image
JSON報文POST
image

看完這些,你敢信這是一家平臺做出來的東西 ?互聯網公司這麼好混的嗎 ?哪裏有事少錢多離家近代碼隨便敲敲的工作請介紹給我!

總之看完這個接口整個人都不好了,非要強行使用平臺要應對這個東西也不是不行,只是非常非常的麻煩,相信懂的人應該能明白,就爲了這幾隻接口,咱們至少得建幾個CLI端,還不能完全滿足這個請求URL和報文格式。

唯一的辦法只能自定義平臺通訊類來處理該問題。

後面會單獨起一篇介紹如何自定義平臺通訊類的文,待續。



未完,有時間就完善完善 。。。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章