專案中請求第三方介面踩坑記錄

strongmore發表於2024-03-19

問題程式碼

@Slf4j
public class TestWechat {

    public <T extends WxBaseReq, K extends WxBaseResp> K sendV3(T t, String method, Class<K> kClass) {
        K k = null;
        String body = JSON.toJSONString(t);
        String apiUrl = "";//請求API
        log.info("wechat http v3 requestUrl :{} ,body:{}", apiUrl, body);
        ResponseEntity<K> responseEntity = null;
        Long startTime = System.currentTimeMillis();
        try {
            // 有問題的地方
            HttpEntity<T> entity = new HttpEntity<>(t, getHttpHeader("POST", apiUrl, body));
            responseEntity = new RestTemplate().postForEntity(apiUrl, entity, kClass);
            log.info("wechat http v3 response:{}", responseEntity);
            if (responseEntity != null) {
                k = responseEntity.getBody();
            }
        } catch (HttpClientErrorException e) {
            log.info("wechat http v3 HttpClientErrorException:{}", e.getResponseBodyAsString());
            throw e;
        }
        return k;
    }

    private HttpHeaders getHttpHeader(String method, String apiUrl, String body) {
        //設定簽名的請求頭
        return new HttpHeaders();
    }

    public static class WxBaseReq {

    }

    public static class WxBaseResp {

    }
}

問題描述

我們在使用 getHttpHeader() 方法計算簽名時,使用的是 t 物件轉換為 json 後的字串,而網路請求中傳輸過去的是 t 物件,網路框架預設使用 jackson 來序列化物件,而這裡我們使用了 fastjson,兩者結果不一致,導致最終簽名錯誤。

解決方式

HttpEntity<T> entity = new HttpEntity<>(body, getHttpHeader("POST", apiUrl, body));

將json 字串透過網路傳輸,這樣就不會受不同 json 框架的影響了。

相關文章