zoukankan      html  css  js  c++  java
  • Java 调用http接口(基于OkHttp的Http工具类方法示例)

    Java 调用http接口(基于OkHttp的Http工具类方法示例)

    现在的互联网项目中,自己单撸所有功能的时代已经过去了,有些功能往往有第三方或者公司其他团队提供服务,你要做得仅仅就是和它们进行对接。对接一些大公司提供的服务时,它们往往会提供对应语言的SDK和说明文档;而团队与团队之间的项目对接往往通过接口进行数据交互,往往都是HTTP JSON交互的形式。

    本文介绍如何使用这些API,然后给出博主自己写的一个工具列demo,需要的可以在此基础上修改。

    OkHttp3

    一般来说,Java 直接调用HTTP接口常见的有三种方式,第一种是JDK原生的方式,第二种是apache 提供的HTTP工具,还有一种是本文着重介绍的OkHttp3工具

    OkHttp3官方文档介绍了它的4点优势:

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

    使用OkHttp很容易。它的请求/响应API设计为流畅的构建器和不变性。它同时支持同步阻塞调用和带回调的异步调用。

    下面介绍一下常见的GET方法和POST方法官方示例,首先添加依赖:

    MAVEN依赖

    <!--okhttp依赖-->
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.0.0</version>
    </dependency>
    

    Http get操作示例

    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();
      }
    }
    

    Http Post操作示例

    public static final MediaType JSON
        = MediaType.get("application/json; charset=utf-8");
    
    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();
      }
    }
    

    Http 超时控制

    当调用的对等方不可用时,超时使调用失败。网络可能是由于客户机连接问题、服务器可用性问题或两者之间的任何问题造成的。OkHttp支持连接、读取和写入超时。

    private final OkHttpClient client;
    
    public ConfigureTimeouts() throws Exception {
        client = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();
        }
    
    public void run() throws Exception {
        Request request = new Request.Builder()
            .url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
            .build();
    
        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response completed: " + response);
        }
    }
    

    工具类示例

    提供同步的GET和POST调用工具方法示例,提供了异步调用HTTP接口的demo

    import okhttp3.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.HttpMethod;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.util.CollectionUtils;
    
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Consumer;
    
    /**
     * @author axin
     * @since 2019-08-14
     */
    public class OkHttpUtils {
    
        private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class);
    
        private static final String HTTP_JSON = "application/json; charset=utf-8";
        private static final String HTTP_FORM = "application/x-www-form-urlencoded; charset=utf-8";
    
        private static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .build();
    
    
        /**
         * get请求
         * 对于小文档,响应体上的string()方法非常方便和高效。
         * 但是,如果响应主体很大(大于1 MB),则应避免string(),
         * 因为它会将整个文档加载到内存中。在这种情况下,将主体处理为流。
         *
         * @param url
         * @return
         */
        public static String httpGet(String url) {
            if (url == null || "".equals(url)) {
                log.error("url为null!");
                return "";
            }
    
            Request.Builder builder = new Request.Builder();
            Request request = builder.get().url(url).build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.code() == 200) {
                    log.info("http GET 请求成功; [url={}]", url);
                    return response.body().string();
                } else {
                    log.warn("Http GET 请求失败; [errorCode = {} , url={}]", response.code(), url);
                }
            } catch (IOException e) {
                throw new RuntimeException("同步http GET 请求失败,url:" + url, e);
            }
            return null;
        }
    
        public static String httpGet(String url, Map<String, String> headers) {
            if (CollectionUtils.isEmpty(headers)) {
                return httpGet(url);
            }
    
            Request.Builder builder = new Request.Builder();
            headers.forEach((String key, String value) -> builder.header(key, value));
            Request request = builder.get().url(url).build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.code() == 200) {
                    log.info("http GET 请求成功; [url={}]", url);
                    return response.body().string();
                } else {
                    log.warn("Http GET 请求失败; [errorxxCode = {} , url={}]", response.code(), url);
                }
            } catch (IOException e) {
                throw new RuntimeException("同步http GET 请求失败,url:" + url, e);
            }
            return null;
        }
    
        /**
         * 同步 POST调用 无Header
         *
         * @param url
         * @param json
         * @return
         */
        public static String httpPostJson(String url, String json) {
            if (url == null || "".equals(url)) {
                log.error("url为null!");
                return "";
            }
    
            MediaType JSON = MediaType.parse(HTTP_JSON);
            RequestBody body = RequestBody.create(JSON, json);
            Request.Builder requestBuilder = new Request.Builder().url(url);
            Request request = requestBuilder.post(body).build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.code() == 200) {
                    log.info("http Post 请求成功; [url={}, requestContent={}]", url, json);
                    return response.body().string();
                } else {
                    log.warn("Http POST 请求失败; [ errorCode = {}, url={}, param={}]", response.code(), url, json);
                }
            } catch (IOException e) {
                throw new RuntimeException("同步http请求失败,url:" + url, e);
            }
            return null;
        }
    
        /**
         * 同步 POST调用 有Header
         *
         * @param url
         * @param headers
         * @param json
         * @return
         */
        public static String httpPostJson(String url, Map<String, String> headers, String json) {
            if (CollectionUtils.isEmpty(headers)) {
                httpPostJson(url, json);
            }
    
            MediaType JSON = MediaType.parse(HTTP_JSON);
            RequestBody body = RequestBody.create(JSON, json);
            Request.Builder requestBuilder = new Request.Builder().url(url);
            headers.forEach((k, v) -> requestBuilder.addHeader(k, v));
            Request request = requestBuilder.post(body).build();
            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.code() == 200) {
                    log.info("http Post 请求成功; [url={}, requestContent={}]", url, json);
                    return response.body().string();
                } else {
                    log.warn("Http POST 请求失败; [ errorCode = {}, url={}, param={}]", response.code(), url, json);
                }
            } catch (IOException e) {
                throw new RuntimeException("同步http请求失败,url:" + url, e);
            }
            return null;
        }
    
        /**
         * 提交表单
         * @param url
         * @param content
         * @param headers
         * @return
         */
        public static String postDataByForm(String url, String content, Map<String, String> headers) {
            MediaType JSON = MediaType.parse(HTTP_FORM);
            RequestBody body = RequestBody.create(JSON, content);
    
            Request.Builder requestBuilder = new Request.Builder().url(url);
            if (headers != null && headers.size() > 0) {
                headers.forEach((k, v) -> requestBuilder.addHeader(k, v));
            }
            Request request = requestBuilder
                    .post(body)
                    .build();
    
            Response response = null;
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.code() == 200) {
                    log.info("postDataByForm; [postUrl={}, requestContent={}, responseCode={}]", url, content, response.code());
                    return response.body().string();
                } else {
                    log.warn("Http Post Form请求失败,[url={}, param={}]", url, content);
                }
            } catch (IOException e) {
                log.error("Http Post Form请求失败,[url={}, param={}]", url, content, e);
                throw new RuntimeException("Http Post Form请求失败,url:" + url);
            }
            return null;
        }
    
        /**
         * 异步Http调用参考模板:Get、Post、Put
         * 需要异步调用的接口一般情况下你需要定制一个专门的Http方法
         *
         * @param httpMethod
         * @param url
         * @param content
         * @return
         */
        @Deprecated
        public static Future<Boolean> asyncHttpByJson(HttpMethod httpMethod, String url, Map<String, String> headers, String content) {
            MediaType JSON = MediaType.parse(HTTP_JSON);
            RequestBody body = RequestBody.create(JSON, content);
    
            Request.Builder requestBuilder = new Request.Builder()
                    .url(url);
    
            if (!CollectionUtils.isEmpty(headers)) {
                headers.forEach((key, value) -> requestBuilder.header(key, value));
            }
    
            switch (httpMethod) {
                case GET:
                    requestBuilder.get();
                    break;
                case POST:
                    requestBuilder.post(body);
                    break;
                default:
            }
    
            Request request = requestBuilder.build();
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    log.error("异步http {} 请求失败,[url={}, param={}]", httpMethod.name(), url, content);
                    throw new RuntimeException("异步http请求失败,url:" + url);
                }
    
                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    if (response.code() == 200) {
                        System.out.println("需要加入异步回调操作");
                    } else {
                        log.error("异步http {} 请求失败,错误码为{},请求参数为[url={}, param={}]", httpMethod.name(), response.code(), url, content);
                    }
                }
            });
            return new AsyncResult(true);
        }
    
        /**
         * lambda表达式异步调用http模板,不建议使用
         *
         * @param request
         * @param failure
         * @param respConsumer
         */
        public static void asyncCall(Request request, Consumer<Exception> failure, Consumer<Response> respConsumer) {
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    failure.accept(e);
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    respConsumer.accept(response);
                }
            });
        }
    
        //test
        public static void main(String[] args) {
            String url = "http://www.baidu.com";
            System.out.println(httpGet(url));
        }
    
    }
    

    综上,本文介绍了Okhttp3的使用,并给出了工具类的demo,要注意的是,对于异步调用http方法需要根据你们项目的具体业务进行改造,增加回调失败与成功的业务逻辑。

    文档链接:OkHttp官网

  • 相关阅读:
    数据结构问题总结
    基础dp问题总结
    搜索问题总结
    二分+贪心check问题总结
    基础图论问题总结
    数学问题总结
    匹配与网络流学习笔记(在学习中)
    我的第一篇题解
    python+Sqlite+Dataframe打造金融股票数据结构
    用Pandas Dataframe来抓取重构金融股票的各种业务&数据形态
  • 原文地址:https://www.cnblogs.com/keeya/p/11368791.html
Copyright © 2011-2022 走看看