問題程式碼
@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 框架的影響了。