乱码案件

2021-07-28 11:04:18 浏览数 (1)

经过

代码语言:javascript复制
  最近新做了一个需求,需要通过https远程调用第三方接口。之前也对接过一些接口,只不过之前对接的接口的报文编码格式基本上都是UTF-8,而这次对接的是GBK。
  一顿操作之后和对端的接口终于通了,不过却发现对方返回的报文出现一堆问号乱码。开始以为底层的实现没有做URLDecoder(实际上即使没做也不应该出现问号乱码),后面尝试了下发现不是这个原因。于是考虑可能是接收报文处理的地方没有使用正确的编码格式。
我们这边的处理应答码报文的工具类大概如下:
代码语言:javascript复制
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格式解码导致


后续

代码语言:javascript复制
  其实到这里已经知道如何解决,就是自己指定默认的编码格式为GBK。不过想到之前有收藏过一张乱码原因的图,回头看了下有一个场景和这个正好相符(以GBK写中文UTF-8读)。这里贴出来,方便后续快速定位问题。

0 人点赞