OkHttpClient请求方式详解,及常用OkHttpUtils配置工具类

OkHttpClient使用详解,及使用连接池的OkHttpUtils工具类

HTTP是现代应用程序联网的方式。这是我们交换数据和媒体的方式。高效地使用HTTP可以使您的内容加载更快,并节省带宽。

OkHttp是一个HTTP客户端,默认情况下是高效的:

  • HTTP/2支持允许对同一主机的所有请求共享一个套接字。
  • 连接池可以减少请求延迟(如果HTTP/2不可用)。
  • 透明GZIP压缩下载大小。
  • 响应缓存完全避免了重复请求的网络。

当网络出现问题时,OkHttp会坚持下去:它会从常见的连接问题中静默地恢复。如果您的服务有多个IP地址,如果第一次连接失败,OkHttp将尝试替代地址。这对于IPv4+IPv6以及托管在冗余数据中心的业务是必要的。OkHttp支持现代TLS特性(TLS 1.3, ALPN,证书固定)。它可以配置为后退以获得广泛连接。

使用OkHttp很简单。它的请求/响应API采用流畅构建器和不可变设计。它既支持同步阻塞调用,也支持带回调的异步调用。

github链接地址: (GitHub - square/okhttp: Square’s meticulous HTTP client for the JVM, Android, and GraalVM.)

官方项目地址:[Overview - OkHttp (square.github.io)](https://square.github.io/okhttp/)

请求方法详解

我们编写了一些方法,演示如何使用 OkHttp 解决常见问题。通读它们,了解一切如何协同工作。自由剪切和粘贴这些示例;这就是他们的目的。

Get

import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class GetExample {
  final OkHttpClient client = new OkHttpClient();

  String run(String url) throws IOException {
    Request request = new Request.Builder()
        .url(url)
        .build();

    try (Response response = client.newCall(request).execute()) {
      return response.body().string();
    }
  }

  public static void main(String[] args) throws IOException {
    GetExample example = new GetExample();
    String response = example.run("https://raw.github.com/square/okhttp/master/README.md");
    System.out.println(response);
  }
}

POST

import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class PostExample {
  public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

  final OkHttpClient client = new OkHttpClient();

  String post(String url, String json) throws IOException {
    RequestBody body = RequestBody.create(json, JSON);
    Request request = new Request.Builder()
        .url(url)
        .post(body)
        .build();
    try (Response response = client.newCall(request).execute()) {
      return response.body().string();
    }
  }

  String bowlingJson(String player1, String player2) {
    return "{'winCondition':'HIGH_SCORE',"
        + "'name':'Bowling',"
        + "'round':4,"
        + "'lastSaved':1367702411696,"
        + "'dateStarted':1367702378785,"
        + "'players':["
        + "{'name':'" + player1 + "','history':[10,8,6,7,8],'color':-13388315,'total':39},"
        + "{'name':'" + player2 + "','history':[6,10,5,10,10],'color':-48060,'total':41}"
        + "]}";
  }

  public static void main(String[] args) throws IOException {
    PostExample example = new PostExample();
    String json = example.bowlingJson("Jesse", "Jake");
    String response = example.post("http://www.roundsapp.com/post", json);
    System.out.println(response);
  }
}

Asynchronous Get

OkHttp提供enqueue方法来异步执行请求,并提供一个Callback方法来处理回调。

案例:在工作线程上下载一个文件,并在响应可读时返回。回调是在响应标头准备好之后执行的,读取响应体可能仍然会阻塞。OkHttp现阶段不提供异步api来接收响应体。

private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();

    client.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        e.printStackTrace();
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        try (ResponseBody responseBody = response.body()) {
          if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

          Headers responseHeaders = response.headers();
          for (int i = 0, size = responseHeaders.size(); i < size; i++) {
            System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
          }

          System.out.println(responseBody.string());
        }
      }
    });
  }

上述简单介绍了主要的几种请求方式的案例,其它的请求方式皆可根据上述进行眼神。

更多案例详情,比如Post方式提交String, Post方式提交流,响应缓存等,可以参考官网的请求案例讲解:

[Recipes - OkHttp (square.github.io)](https://square.github.io/okhttp/recipes/)

OkHttpUtils工具类

@Slf4j
public class OkHttpUtils {

	// 方式一
    private static OkHttpClient okHttpClient = null;
    
    public static OkHttpClient getOkHttpClient(){
        if (okHttpClient != null){
            return okHttpClient;
        }

        // 加锁
        synchronized (OkHttp3Demo.class){
            // 自定义连接池最大空闲连接数和等待时间大小,否则默认最大10个空闲连接
            ConnectionPool connectionPool = new ConnectionPool(32, 10, TimeUnit.MINUTES);
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(30, TimeUnit.SECONDS) // 连接超时
                    .writeTimeout(20,TimeUnit.SECONDS)  // 写入超时
                    .readTimeout(20,TimeUnit.SECONDS) // 读取超时
                    .connectionPool(connectionPool)	// 
                    // .addInterceptor() 添加应用拦截器
                    // .addNetworkInterceptor() 添加网络拦截器
                    // .cache() 设置缓存
                    .build();
        }
        return client;
    }
    
        // 创建OkHttpClient对象, 并设置超时时间 
    private static final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .build();

    /**
     * 同步GET请求
     *
     * @param url 请求地址
     */
    public static String getRequest(String url) {
        try {
            // 1 创建OkHttpClient对象 
            // 2 构建Request对象
            Request request = new Request.Builder()
                    .get()// 不写默认为GET请求
                    .url(url)
                    .build();
            // 3 发起请求获取响应值
            Response response = client.newCall(request).execute();
            // 4 根据响应结果判断
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new RuntimeException("请求异常,错误码为: " + response.code());
            }
        } catch (Exception e) {
            log.info("请求失败,错误信息为= {} ", e.getMessage());
        }
        return null;
    }
    
    /**
     * 同步POST请求
     *
     * @param url 请求地址
     * @param params 请求参数
     */
    public static String postRequest(String url, Map<String, String> params) {

        try {
            // 1 创建OkHttpClient对象
            // 2 构建请求体
            MultipartBody body = new MultipartBody.Builder()
                    .setType(MediaType.parse("multipart/form-data"))
                    .addFormDataPart("username", params.get("username"))
                    .addFormDataPart("password", params.get("password"))
                    .build();
            // 3 构建Request对象
            Request request = new Request.Builder()
                    .post(body)
                    .url(url)
                    .build();
            // 4 发起请求获取响应值
            Response response = client.newCall(request).execute();

            // 5 根据响应结果判断
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new RuntimeException("请求异常,错误码为: " + response.code());
            }
        } catch (Exception e) {
            log.info("请求失败,错误信息为= {} ", e.getMessage());
        }
        return null;
    }
    
    
    /**
     * 同步GET请求
     */
    public static String getRequest(String url) throws IOException {
        Request request = new Builder().url(url).build();
        Response response = execute(request);

        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new ArithmeticException("请求异常,错误码为: " + response.code());
        }

    }

    /**
     * 同步请求
     */
    public static Response execute(Request request) throws IOException {
        return client.newCall(request).execute();
    }
    
    /**
     * 开启异步线程访问网络, 需要返回结果
     */
    public static void enqueue(Request request, Callback callback) {
        client.newCall(request).enqueue(callback);
    }

    /**
     * 开启异步线程访问网络,不需要返回结果( Callback 返回为空)
     */
    public static void enqueue(Request request) {
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                log.info("请求失败,异常信息为: {} ", e.getMessage());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response)
                    throws IOException {
                log.info("请求成功");
            }
        });
    }
    
}

参考文献:

Java中发送Http请求之OkHttpClient

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JermeryBesian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值