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