折腾:
【未解决】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" ); / / 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
我刚用猜到,估计是用了压缩导致的,去掉:
1 | .header( "Accept-Encoding" , "gzip, deflate, br" ) |
结果:
就不是乱码了:

【总结】
此处是在OkHttp的请求中加上了:
1 | .header( "Accept-Encoding" , "gzip, deflate, br" ) |
导致返回的是gzip压缩后的数据
-》直接打印就是乱码
解决办法:
要么自己去想办法解压缩
要么直接去掉Accept-Encoding
如果不加,则OkHttp会自动加上,以及加压缩返回的字符串
详见:
转载请注明:在路上 » 【已解决】OkHttp返回响应的字符串是乱码