最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

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

字符串 crifan 3736浏览 0评论
折腾:
【未解决】Java中如何保存字符串到文件中且指定编码
期间,用代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
我刚用猜到,估计是用了压缩导致的,去掉:
1
.header("Accept-Encoding", "gzip, deflate, br")
结果:
就不是乱码了:
【总结】
此处是在OkHttp的请求中加上了:
1
.header("Accept-Encoding", "gzip, deflate, br")
导致返回的是gzip压缩后的数据
-》直接打印就是乱码
解决办法:
要么自己去想办法解压缩
要么直接去掉Accept-Encoding
如果不加,则OkHttp会自动加上,以及加压缩返回的字符串
详见:
java – Retrofit and OkHttp gzip decode – Stack Overflow

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

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
80 queries in 0.387 seconds, using 19.14MB memory