Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

OkHttp3使用教程,实现get、post请求发送,自动重试,打印响应日志。

弘文馆校书 2019-09-21 10:14:00 阅读数:29 评论数:0 点赞数:0 收藏数:0

一、创建线程安全的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();
}
}
 

 

重试拦截器:

 import okhttp3.Interceptor;
 import okhttp3.Request;
 import okhttp3.Response;
 
 import java.io.IOException;
 
 
 public class RetryIntercepter implements Interceptor{
     public int maxRetryCount;
     private int count = 0;
     public RetryIntercepter(int maxRetryCount) {
         this.maxRetryCount = maxRetryCount;
     }
 
     @Override
     public Response intercept(Chain chain) throws IOException {
 
         return retry(chain);
     }
 
     public Response retry(Chain chain){
         Response response = null;
         Request request = chain.request();
         try {
             response = chain.proceed(request);
             while (!response.isSuccessful() && count < maxRetryCount) {
                 count++;
                 response = retry(chain);
             }
         }
         catch (Exception e){
             while (count < maxRetryCount){
                 count++;
                 response = retry(chain);
             }
         }
         return response;
     }
 }

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

 

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

 import okhttp3.*;
 import okio.Buffer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
 
 
 public class NetworkIntercepter implements Interceptor{
     private static Logger LOGGER = LoggerFactory.getLogger(NetworkIntercepter.class);
     @Override
     public Response intercept(Interceptor.Chain chain) {
         long start = System.currentTimeMillis();
         Response response=null;
         String responseBody = null;
         String responseCode = null;
         String url = null;
         String requestBody = null;
         try {
             Request request = chain.request();
             url = request.url().toString();
             requestBody = getRequestBody(request);
             response = chain.proceed(request);
             responseBody = response.body().string();
             responseCode = String.valueOf(response.code());
             MediaType mediaType = response.body().contentType();
             response = response.newBuilder().body(ResponseBody.create(mediaType,responseBody)).build();
         }
         catch (Exception e){
             LOGGER.error(e.getMessage());
         }
         finally {
             long end = System.currentTimeMillis();
             String duration = String.valueOf(end - start);
             LOGGER.info("responseTime= {}, requestUrl= {}, params={}, responseCode= {}, result= {}",
                         duration, url,requestBody,responseCode,responseBody);
         }
 
         return response;
     }
 
     private String getRequestBody(Request request) {
         String requestContent = "";
         if (request == null) {
             return requestContent;
         }
         RequestBody requestBody = request.body();
         if (requestBody == null) {
             return requestContent;
         }
         try {
             Buffer buffer = new Buffer();
             requestBody.writeTo(buffer);
             Charset charset = Charset.forName("utf-8");
             requestContent = buffer.readString(charset);
         } catch (IOException e) {
             e.printStackTrace();
         }
         return requestContent;
     }
 }

 

 

二、GET请求

1、带参数的get请求

 /*
     * 发送待url参数的get
     */
     public String get(String url,Map<String,String> pathParams){
         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
         for(String key:pathParams.keySet()){
             builder.addQueryParameter(key,pathParams.get(key) );
         }
         Request request = new Request.Builder()
                 .url(builder.build().toString())
                 .build();
         return execute(request);
     }
 
 private String execute(Request request){
         String responseBody=null;
         try {
             Response response = okHttpClient.newCall(request).execute();
             responseBody = response.body().string();
         } catch (IOException |NullPointerException e) {
             e.printStackTrace();
         }
         return responseBody;
     }

测试:

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

 /*
     * post发送带url参数的json
     */
     public String post(String url, Map<String,String> pathParams, String body){
         RequestBody requestBody = RequestBody.
                 create(MediaType.parse("application/json;charset=utf-8"), body);
         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
         for(String key:pathParams.keySet()){
             builder.addQueryParameter(key,pathParams.get(key) );
         }
         Request request = new Request.Builder()
                 .post(requestBody)
                 .url(builder.build().toString())
                 .build();
         return execute(request);
     }

 测试:

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

 /*
     * post发送json
     */
     public String post(String url,String body){
         Map<String,String> pathParams = new HashMap<>();
         return post(url,pathParams ,body );
     }

 

测试:

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发送表单

  /*
     * post发送表单
     */
     public String post(String url, Map<String,String> pathParams){
         FormBody.Builder formBodyBuilder = new FormBody.Builder();
         HttpUrl.Builder builder = HttpUrl.parse(url).newBuilder();
         for(String key:pathParams.keySet()){
             formBodyBuilder.add(key,pathParams.get(key) );
         }
         RequestBody requestBody = formBodyBuilder.build();
         Request request = new Request.Builder()
                 .post(requestBody)
                 .url(builder.build().toString())
                 .build();
         return execute(request);
     }

 

测试:

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




版权声明
本文为[弘文馆校书]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/Eric-zhao/p/11561578.html