最新消息:20210917 已从crifan.com换到crifan.org

【已解决】OkHttp返回响应的字符串是乱码

字符串 crifan 1199浏览 0评论
折腾:
【未解决】Java中如何保存字符串到文件中且指定编码
期间,用代码:

class LoggingInterceptor implements Interceptor {
    @Override public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
//        logger.info(String.format("Sending request %s on %s%n%s",
//                request.url(), chain.connection(), request.headers()));
        Logger.info("Sending request url={} on connection={}, headers={}",
                request.url(), chain.connection(), request.headers());

        Response response = chain.proceed(request);

        long t2 = System.nanoTime();
//        logger.info(String.format("Received response for %s in %.1fms%n%s",
//                response.request().url(), (t2 - t1) / 1e6d, response.headers()));
        Logger.info("Received response for url={} in {}, headers={}",
                response.request().url(), (t2 - t1) / 1e6d, response.headers());

        return response;
    }
}

class ResponseInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        ResponseBody body = response.body();
        String bodyString = body.string();
        MediaType contentType = body.contentType();
        Logger.debug("Response={}", bodyString);
        return response.newBuilder().body(ResponseBody.create(contentType, bodyString)).build();
    }
}


public class EmulateLoginBaidu {
//    OkHttpClient client = new OkHttpClient();
    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new LoggingInterceptor())
        .addInterceptor(new ResponseInterceptor())
        .build();

    String UserAgent_Mac_Chrome = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36";

//    ResponseBody run(String url) throws IOException {
    Response run(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .header("User-Agent", UserAgent_Mac_Chrome)
                .header("Host", "www.baidu.com")
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
                .header("Cache-Control", "no-cache")
                .build();

        try (Response response = client.newCall(request).execute()) {
//            return response.body().string();
//            return response.body();
            return response;
        }
    }

    public static void main(String[] args) throws IOException {
        String logFilename = "log/EmulateLoginBaidu.log";
        CrifanUtil.initLogger(logFilename);

        Logger.info("logFilename={}", logFilename);
        Logger.info("Try Emulate Login Baidu");

        String baiduUrl = "http://www.baidu.com";
//        Logger.info("baiduUrl=%s", baiduUrl);
        Logger.info("baiduUrl={}", baiduUrl);

        EmulateLoginBaidu emulateLogin = new EmulateLoginBaidu();
//        ResponseBody respBody = emulateLogin.run(baiduUrl);
        Response response = emulateLogin.run(baiduUrl);

        ResponseBody respBody = response.body();
        String respBodyStr = respBody.string();
//        String respBodyStr = response.body().string();
        Logger.info("respBodyStr={}", respBodyStr);

        try (PrintWriter printWriter = new PrintWriter("debug/baidu_com.html")) {
            printWriter.println(respBodyStr);
        }
    }
}
发现OkHttp虽然可以返回字符串了,但是全是乱码:
不论是console(UTF-8编码)中:
还是UTF-8的log文件中:
而本身网站的编码,去Chrome中调试确定是utf-8的:
okhttp body string messy code
android – OkHttp returning unreadable characters – Stack Overflow
我刚用猜到,估计是用了压缩导致的,去掉:
.header("Accept-Encoding", "gzip, deflate, br")
结果:
就不是乱码了:
【总结】
此处是在OkHttp的请求中加上了:
.header("Accept-Encoding", "gzip, deflate, br")
导致返回的是gzip压缩后的数据
-》直接打印就是乱码
解决办法:
要么自己去想办法解压缩
要么直接去掉Accept-Encoding
如果不加,则OkHttp会自动加上,以及加压缩返回的字符串
详见:
java – Retrofit and OkHttp gzip decode – Stack Overflow

转载请注明:在路上 » 【已解决】OkHttp返回响应的字符串是乱码

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
90 queries in 0.183 seconds, using 23.37MB memory