• okHttp3教程:5种基本请求示例,拦截器实现自动重试和日志打印


    一、创建线程安全的okhttp单例

    
    
    import service.NetworkIntercepter;
    import service.RetryIntercepter;
    import okhttp3.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;

    public class HttpUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);
    private static final int CONNECTION_TIME_OUT = 2000;//连接超时时间
    private static final int SOCKET_TIME_OUT = 2000;//读写超时时间
    private static final int MAX_IDLE_CONNECTIONS = 30;// 空闲连接数
    private static final long KEEP_ALLIVE_TIME = 60000L;//保持连接时间

    private OkHttpClient okHttpClient;
    private volatile static HttpUtils httpUtils;

    public static HttpUtils getInstance(){
    if(httpUtils == null){
    synchronized (HttpUtils.class){
    if(httpUtils == null){
    httpUtils = new HttpUtils();
    }
    }
    }
    return httpUtils;

    }
    public HttpUtils(){
    ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS,KEEP_ALLIVE_TIME,TimeUnit.MILLISECONDS);
    this.okHttpClient = new OkHttpClient()
    .newBuilder()
    .readTimeout(SOCKET_TIME_OUT, TimeUnit.MILLISECONDS)
    .writeTimeout(SOCKET_TIME_OUT, TimeUnit.MILLISECONDS)
    .connectionPool(connectionPool)
    .retryOnConnectionFailure(false) //自动重连设置为false
    .connectTimeout(CONNECTION_TIME_OUT,TimeUnit.MILLISECONDS)
    .addInterceptor(new RetryIntercepter(2)) //重试拦截器2次
    .addNetworkInterceptor(new NetworkIntercepter()) //网络拦截器,统一打印日志
    .build();
    }
    }
     

    重试拦截器:

     1 import okhttp3.Interceptor;
     2 import okhttp3.Request;
     3 import okhttp3.Response;
     4 
     5 import java.io.IOException;
     6 
     7 
     8 public class RetryIntercepter implements Interceptor{
     9     public int maxRetryCount;
    10     private int count = 0;
    11     public RetryIntercepter(int maxRetryCount) {
    12         this.maxRetryCount = maxRetryCount;
    13     }
    14 
    15     @Override
    16     public Response intercept(Chain chain) throws IOException {
    17 
    18         return retry(chain);
    19     }
    20 
    21     public Response retry(Chain chain){
    22         Response response = null;
    23         Request request = chain.request();
    24         try {
    25             response = chain.proceed(request);
    26             while (!response.isSuccessful() && count < maxRetryCount) {
    27                 count++;
    28                 response = retry(chain);
    29             }
    30         }
    31         catch (Exception e){
    32             while (count < maxRetryCount){
    33                 count++;
    34                 response = retry(chain);
    35             }
    36         }
    37         return response;
    38     }
    39 }

    注意:两处while是因为如果请求中出现异常,也能进行重试,比如超时,后面会有例子。

    网络拦截器,打印请求、响应时间、响应状态码,响应内容

     1 import okhttp3.*;
     2 import okio.Buffer;
     3 import org.slf4j.Logger;
     4 import org.slf4j.LoggerFactory;
     5 
     6 import java.io.IOException;
     7 import java.nio.charset.Charset;
     8 
     9 
    10 public class NetworkIntercepter implements Interceptor{
    11     private static Logger LOGGER = LoggerFactory.getLogger(NetworkIntercepter.class);
    12     @Override
    13     public Response intercept(Interceptor.Chain chain) {
    14         long start = System.currentTimeMillis();
    15         Response response=null;
    16         String responseBody = null;
    17         String responseCode = null;
    18         String url = null;
    19         String requestBody = null;
    20         try {
    21             Request request = chain.request();
    22             url = request.url().toString();
    23             requestBody = getRequestBody(request);
    24             response = chain.proceed(request);
    25             responseBody = response.body().string();
    26             responseCode = String.valueOf(response.code());
    27             MediaType mediaType = response.body().contentType();
    28             response = response.newBuilder().body(ResponseBody.create(mediaType,responseBody)).build();
    29         }
    30         catch (Exception e){
    31             LOGGER.error(e.getMessage());
    32         }
    33         finally {
    34             long end = System.currentTimeMillis();
    35             String duration = String.valueOf(end - start);
    36             LOGGER.info("responseTime= {}, requestUrl= {}, params={}, responseCode= {}, result= {}",
    37                         duration, url,requestBody,responseCode,responseBody);
    38         }
    39 
    40         return response;
    41     }
    42 
    43     private String getRequestBody(Request request) {
    44         String requestContent = "";
    45         if (request == null) {
    46             return requestContent;
    47         }
    48         RequestBody requestBody = request.body();
    49         if (requestBody == null) {
    50             return requestContent;
    51         }
    52         try {
    53             Buffer buffer = new Buffer();
    54             requestBody.writeTo(buffer);
    55             Charset charset = Charset.forName("utf-8");
    56             requestContent = buffer.readString(charset);
    57         } catch (IOException e) {
    58             e.printStackTrace();
    59         }
    60         return requestContent;
    61     }
    62 }

    二、GET请求

    1、带参数的get请求

     1 /*
     2     * 发送待url参数的get
     3     */
     4     public String get(String url,Map<String,String> pathParams){
     5         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
     6         for(String key:pathParams.keySet()){
     7             builder.addQueryParameter(key,pathParams.get(key) );
     8         }
     9         Request request = new Request.Builder()
    10                 .url(builder.build().toString())
    11                 .build();
    12         return execute(request);
    13     }
    14 
    15 private String execute(Request request){
    16         String responseBody=null;
    17         try {
    18             Response response = okHttpClient.newCall(request).execute();
    19             responseBody = response.body().string();
    20         } catch (IOException |NullPointerException e) {
    21             e.printStackTrace();
    22         }
    23         return responseBody;
    24     }

    测试:

    String url = "http://localhost:8080/test/12346/query";
    Map<String,String> params = new HashMap<>();
    params.put("aaa","111");
    params.put("bbb","222");
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.get(url,params);

    打印日志如下:
    [main][2019-09-21 10:19:02.072] [INFO] [NetworkIntercepter.intercept:40] responseTime= 62, requestUrl= http://localhost:8080/test/12346/query?aaa=111&bbb=222, params=, responseCode= 200, result= {"result_code":"success","data":{"aaa":"111"},"path":"/test/12346/query"}

     2、不带参数的get请求

    测试:

    String url = "http://localhost:8080/test/12346/query?ccc=1&ddd=2";
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.get(url);

    打印日志如下:
    [main][2019-09-21 10:25:46.943] [INFO] [NetworkIntercepter.intercept:38] responseTime= 11, requestUrl= http://localhost:8080/test/12346/query?ccc=1&ddd=2, params=, responseCode= 200, result= {"result_code":"success","data":{"aaa":"111"},"path":"/test/12346/query"}


    三、POST请求

    1、post发送带url参数的json

     1 /*
     2     * post发送带url参数的json
     3     */
     4     public String post(String url, Map<String,String> pathParams, String body){
     5         RequestBody requestBody = RequestBody.
     6                 create(MediaType.parse("application/json;charset=utf-8"), body);
     7         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
     8         for(String key:pathParams.keySet()){
     9             builder.addQueryParameter(key,pathParams.get(key) );
    10         }
    11         Request request = new Request.Builder()
    12                 .post(requestBody)
    13                 .url(builder.build().toString())
    14                 .build();
    15         return execute(request);
    16     }

     测试:

    Gson gson = new Gson();
    String url = "http://localhost:8080/test/12346/query";
    Map<String,String> params = new HashMap<>();
    params.put("aaa","111");
    params.put("bbb","222");

    Map<String,Object> bodyMap = new HashMap<>();
    bodyMap.put("name","zhangsan");
    bodyMap.put("age",15);
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.post(url,params,gson.toJson(bodyMap));

    打印日志
    [main][2019-09-21 10:37:04.577] [INFO] [NetworkIntercepter.intercept:38] responseTime= 304, requestUrl= http://localhost:8080/test/12346/query?aaa=111&bbb=222, params={"name":"zhangsan","age":15}, responseCode= 200, result= {"result_code":"success","data":{"aaa":"111"},"path":"/test/12346/query"}    

    2、post发送json

    1 /*
    2     * post发送json
    3     */
    4     public String post(String url,String body){
    5         Map<String,String> pathParams = new HashMap<>();
    6         return post(url,pathParams ,body );
    7     }

    测试:

    Gson gson = new Gson();
    String url = "http://localhost:8080/test/12346/query";
    Map<String,Object> bodyMap = new HashMap<>();
    bodyMap.put("name","zhangsan");
    bodyMap.put("age",15);
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.post(url,gson.toJson(bodyMap));

    打印日志:

    [main][2019-09-21 10:44:00.835] [INFO] [NetworkIntercepter.intercept:38] responseTime= 17, requestUrl= http://localhost:8080/test/12346/query, params={"name":"zhangsan","age":15}, responseCode= 200, result= {"result_code":"success","data":{"aaa":"111"},"path":"/test/12346/query"}

    3、post发送表单

     1  /*
     2     * post发送表单
     3     */
     4     public String post(String url, Map<String,String> pathParams){
     5         FormBody.Builder formBodyBuilder = new FormBody.Builder();
     6         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
     7         for(String key:pathParams.keySet()){
     8             formBodyBuilder.add(key,pathParams.get(key) );
     9         }
    10         RequestBody requestBody = formBodyBuilder.build();
    11         Request request = new Request.Builder()
    12                 .post(requestBody)
    13                 .url(builder.build().toString())
    14                 .build();
    15         return execute(request);
    16     }

    测试:

    String url = "http://localhost:8080/test/12346/query";
    Map<String,String> params = new HashMap<>();
    params.put("aaa","111");
    params.put("bbb","222");
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.post(url,params);

    打印日志:
    [main][2019-09-21 10:49:54.136] [INFO] [NetworkIntercepter.intercept:38] responseTime= 21, requestUrl= http://localhost:8080/test/12346/query, params=aaa=111&bbb=222, responseCode= 200, result= {"result_code":"success","data":{"aaa":"111"},"path":"/test/12346/query"}

     四、网络拦截器

    1、404重试

    测试:

    String url = "http://localhost:8080/test/12346/query2";
    Map<String,String> params = new HashMap<>();
    params.put("aaa","111");
    params.put("bbb","222");
    HttpUtils httpUtils = HttpUtils.getInstance();
    httpUtils.post(url,params);

    日志打印:

    [main][2019-09-21 10:56:20.495] [INFO] [NetworkIntercepter.intercept:38] responseTime= 26, requestUrl= http://localhost:8080/test/12346/query2, params=aaa=111&bbb=222, responseCode= 404, result= {"timestamp":1569034580,"status":404,"error":"Not Found","message":"Not Found","path":"/test/12346/query2"}
    [main][2019-09-21 10:56:20.506] [INFO] [NetworkIntercepter.intercept:38] responseTime= 4, requestUrl= http://localhost:8080/test/12346/query2, params=aaa=111&bbb=222, responseCode= 404, result= {"timestamp":1569034580,"status":404,"error":"Not Found","message":"Not Found","path":"/test/12346/query2"}
    [main][2019-09-21 10:56:20.512] [INFO] [NetworkIntercepter.intercept:38] responseTime= 4, requestUrl= http://localhost:8080/test/12346/query2, params=aaa=111&bbb=222, responseCode= 404, result= {"timestamp":1569034580,"status":404,"error":"Not Found","message":"Not Found","path":"/test/12346/query2"


    重试了2次,共请求3次

    2、超时重试

    日志打印:

    [main][2019-09-21 10:59:30.086] [ERROR] [NetworkIntercepter.intercept:33] timeout
    [main][2019-09-21 10:59:30.092] [INFO] [NetworkIntercepter.intercept:38] responseTime= 2009, requestUrl= http://localhost:8080/test/12346/query, params=aaa=111&bbb=222, responseCode= null, result= null
    [main][2019-09-21 10:59:32.097] [ERROR] [NetworkIntercepter.intercept:33] timeout
    [main][2019-09-21 10:59:32.097] [INFO] [NetworkIntercepter.intercept:38] responseTime= 2004, requestUrl= http://localhost:8080/test/12346/query, params=aaa=111&bbb=222, responseCode= null, result= null
    [main][2019-09-21 10:59:34.101] [ERROR] [NetworkIntercepter.intercept:33] timeout
    [main][2019-09-21 10:59:34.101] [INFO] [NetworkIntercepter.intercept:38] responseTime= 2002, requestUrl= http://localhost:8080/test/12346/query, params=aaa=111&bbb=222, responseCode= null, result= null




  • 相关阅读:
    Xshell 跳板机快速登录脚本按钮
    (一)angularjs5 环境搭建
    Myeclipse 内存溢出解决方法
    php 代码放到服务器上验证码不好用
    表格里面的input在底部
    Smarty忽略大括号
    php富友表单提交接口对接
    php富友接口对接http请求
    js去掉html标签
    删除的时候提示是否删除
  • 原文地址:https://www.cnblogs.com/Eric-zhao/p/11561578.html
Copyright © 2020-2023  润新知