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官网
Java 调用http接口(基于OkHttp的Http工具类方法示例)的更多相关文章
- Java调用webservice接口方法
java调用webservice接口 webservice的 发布一般都是使用WSDL(web service descriptive langu ...
- (二)通过JAVA调用SAP接口 (增加一二级参数)
(二)通过JAVA调用SAP接口 (增加一二级参数) 一.建立sap连接 请参考我的上一篇博客 JAVA连接SAP 二.测试项目环境准备 在上一篇操作下已经建好的环境后,在上面的基础上新增类即可 三. ...
- Java调用RestFul接口
使用Java调用RestFul接口,以POST请求为例,以下提供几种方法: 一.通过HttpURLConnection调用 1 public String postRequest(String url ...
- Java调用第三方接口工具类(json、form)
1.JSON值访问 /** * 调用对方接口方法 * @param path 对方或第三方提供的路径 * @param data 向对方或第三方发送的数据,大多数情况下给对方发送JSON数据让对方解析 ...
- java 调用webservice接口wsdl,推荐使用wsdl2java,放弃wsimport
网上说wsimport是jdk1.6后自带的客户端生成调用webservice接口的工具,其实我挺喜欢原生的东西,毕竟自家的东西用着应该最顺手啊,但往往让人惊艳的是那些集成工具. 本机jdk1.8.1 ...
- Java调用第三方接口示范
在项目开发中经常会遇到调用第三方接口的情况,比如说调用第三方的天气预报接口. 使用流程[1]准备工作:在项目的工具包下导入HttpClientUtil这个工具类,或者也可以使用Spring框架的res ...
- 三种方法实现java调用Restful接口
1,基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring ...
- Java 调用 php接口(Ajax)(二)
由于项目里面需要用到Java调用PHP的充值接口,所以学习了一下,以下这个Demo是个小小的例子,写下来做个笔记> jsp页面: <%@ page language="java& ...
- [Java] java调用wsdl接口
前提: ① 已经提供了一个wsdl接口 ② 该接口能正常调用 步骤1:使用cxf的wsdl2java工具生成本地类 下载CXF:http://cxf.apache.org/download.html ...
随机推荐
- web安全测试必须注意的五个方面
随着互联网的飞速发展,web应用在软件开发中所扮演的角色变得越来越重要,同时,web应用遭受着格外多的安全攻击,其原因在于,现在的网站以及在网站上运行的应用在某种意义上来说,它是所有公司或者组织的虚拟 ...
- [Windows无法连接到 System Event Notification Service服务]解决方案
我之前使用Windows的过程的有出现过以下问题,之前因为比较急就匆忙解决了没来得及把解决方法写下来. 正好今天有个朋友电脑也出现此问题过来找我寻求解决方法,便把解决方法写了下来. 电脑出现的问题,如 ...
- 后端 - Lession 01 PHP 基础
目录 Lession 01 php 基础 1. php 基础 2. php 变量 3. php 单引号 和 双引号区别 4. 数据类型 5. 数据类型转换 6. 常量 7. 运算符 8. 为 fals ...
- redis 发布与订阅原理分析
前言:用了redis也有一段时间了,但是发布与订阅的使用频率也不高,趁着这次空闲,深究下redis的发布与订阅模式. 一.订阅频道和信息发布 功能说明:Redis 的 SUBSCRIBE 命令可以让客 ...
- 初识nginx!
What--什么是nginx nginx是一款高性能的http服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.官方测试nginx能够支撑5w并发连接.并且cup.内存等资源消耗却非常 ...
- C#2.0新增功能07 getter/setter 单独可访问性
连载目录 [已更新最新开发文章,点击查看详细] 属性是一种成员,它提供灵活的机制来读取.写入或计算私有字段的值. 属性可用作公共数据成员,但它们实际上是称为访问器的特殊方法. 这使得可以轻松访问 ...
- c实现哲学家进餐问题。WINDOWS下。
// 解决哲学家就餐问题// 每个哲学家可用一个线程来模拟.// 设有5个哲学家,5只筷子,每个哲学家吃饭时间为一个随机值,哲学家吃饭后的思考时间也是一个随机值.#include <Window ...
- docker实战(一)之Tomcat的安装
docker号称分分钟就可以将环境构建完成,这话一点也不假,因为docker在使用软件时只需要从官方 仓库中拉取对应的镜像就行了.docker的使用前需要了解两个名词--镜像和容器.这两 ...
- 用tcp协议实现一个并发的socketserver 进行密文登录
先在客户端进行摘要,客户端把用户名作为盐. 然后在服务端进行二次摘要,用固定的盐(不能让别人知道你的盐是什么),然后存到文件中,密文存储.或者和文件中的密文对比. 这样即使在网络上用户信息被截获,和存 ...
- SQLServer 问题(一)
出现这种错误: [DBNETLIB][ConnectionOpen(Connect()).]SQL Server 不存在或拒绝访问 数据库错误 原因: 1.查看是不是没有在数据库中添加数据库服务器地址 ...