最新消息:20190717 VPS服务器:Vultr新加坡,WordPress主题:大前端D8,统一介绍入口:关于

【已解决】拦截器interceptor的作用和如何实现OkHttp的interceptor

OkHttp crifan 15浏览 0评论
折腾:
【未解决】OkHttp获取响应的body的字符串出错:Exception in thread “main” java.lang.IllegalStateException: closed
期间,发现OkHttp的设计很是垃圾啊,竟然response只能使用一次
导致:连debug打印了一下response,后续都无法继续使用body,以及body的string了。
看到很多提到了:interceptor
貌似可以一劳永逸实现复制一份,供后续使用。
所以去看看:
什么是interceptor
okhttp interceptor
OkHttp 拦截器的一些骚操作 – 掘金
Interceptors · square/okhttp Wiki
OkHttp 3.x 源码解析之Interceptor 拦截器 – Tamic (大白) – CSDN博客
竟然都没写,导入Interceptor的路径。。。真垃圾
Interceptor (OkHttp 3.11.0 API)
好像是okhttp3下面的
果然是:
import okhttp3.Interceptor;
此处顺带也的确需要去实现log的Interceptor
此处先去解决log的问题:
【已解决】Java中好用的Log日志库
然后再去解决interceptor
【总结】
目前用:
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.MediaType;
import okhttp3.Interceptor;

//import java.io.PrintWriter;
//import PrintWriter;
//import FileUtils;


import org.pmw.tinylog.Logger;
import org.pmw.tinylog.Level;
import org.pmw.tinylog.Configurator;
import org.pmw.tinylog.writers.ConsoleWriter;
import org.pmw.tinylog.writers.FileWriter;


//public static void saveStrToFile(fullFilePath, strToSave){
//
//}

//void saveStrToFile(fullFilePath, strToSave){
//
//}

class CrifanUtil {
    public static void initLogger(String logFilename){
        System.out.println("logFilename=" + logFilename);

        FileWriter fileWriter = new FileWriter(logFilename);
        ConsoleWriter consoleWriter = new ConsoleWriter();

        Level fileWriterLevel = Level.TRACE;
//        Level consoleWriterLevel = Level.DEBUG;
        Level consoleWriterLevel = Level.INFO;
        String consoleFormat = "{date:YYMMdd HH:mm:ss} {class}.{method} {{level}|min-size=8}: {message}";
        String fileFormat = "{date:yyyyMMdd HH:mm:ss} [{thread}] {class}.{method} {{level}|min-size=8}: {message}";

        Configurator.currentConfig()
                .writer(consoleWriter, consoleWriterLevel, consoleFormat)
                .addWriter(fileWriter, fileWriterLevel, fileFormat)
                .activate();

//        Logger.trace("trace");
//        Logger.debug("debug");
//        Logger.info("info");
//        Logger.warn("warn");
//        Logger.error("error");
    }
}


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);
        }
    }
}
实现了:
先加log的:LoggingInterceptor
再加重新复制一个response的:ResponseInterceptor
然后最后再去调用
response.body().string()
就不会挂了。

转载请注明:在路上 » 【已解决】拦截器interceptor的作用和如何实现OkHttp的interceptor

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
20 queries in 0.070 seconds, using 9.16MB memory