最近新作了一個需求,須要經過https遠程調用第三方接口。以前也對接過一些接口,只不過以前對接的接口的報文編碼格式基本上都是UTF-8,而此次對接的是GBK。 一頓操做以後和對端的接口終於通了,不過卻發現對方返回的報文出現一堆問號亂碼。開始覺得底層的實現沒有作URLDecoder(實際上即便沒作也不該該出現問號亂碼),後面嘗試了下發現不是這個緣由。因而考慮多是接收報文處理的地方沒有使用正確的編碼格式。 咱們這邊的處理應答碼報文的工具類大概以下:
public class ResponseHandlerHelper { private Charset defaultCharset = StandardCharsets.UTF_8; public ResponseHandlerHelper() { } public ResponseHandlerHelper(Charset defaultCharset) { this.defaultCharset = defaultCharset; } public HttpEntity processResponse(HttpResponse response) throws IOException { StatusLine statusLine = response.getStatusLine(); HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { // 這裏獲取編碼格式 Charset responseCharset = getResponseCharset(entity); String result = EntityUtils.toString(entity, responseCharset); throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase() + ':' + result); } return entity; } public Charset getResponseCharset(HttpEntity entity) { ContentType contentType = ContentType.getOrDefault(entity); // 若是應答碼報文沒有指定編碼格式,則使用默認的UTF-8 Charset charset = contentType.getCharset(); if (charset == null) { charset = defaultCharset; } return charset; } public File copy(InputStream content, File targetFile) throws IOException { try (BufferedInputStream inStream = new BufferedInputStream(content); OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile))) { byte[] buffer = new byte[8192]; int bytesRead = -1; while ((bytesRead = inStream.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } out.flush(); return targetFile; } } }
注意代碼中加註釋的地方。
找到緣由:對方返回報文未指定編碼格式致使使用了默認的UTF-8格式解碼致使。java
其實到這裏已經知道如何解決,就是本身指定默認的編碼格式爲GBK。不過想到以前有收藏過一張亂碼緣由的圖,回頭看了下有一個場景和這個正好相符(以GBK寫中文UTF-8讀)。這裏貼出來,方便後續快速定位問題。