httpclient、okhttp、resttemplate接口调用对比
httpclient、okhttp 和 resttemplate 是三种常用的 java http 客户端库,它们都可以用于发送 http 请求和接收 http 响应,但在一些方面有所不同。
对比总结:
● 性能和效率: okhttp 在性能和效率上通常优于 apache httpclient 和 resttemplate,特别是在并发场景和对性能要求较高的情况下。
● 功能和灵活性: apache httpclient 提供了更丰富的功能和灵活的配置选项,适用于需要定制化的场景;而 okhttp 和 resttemplate 则更加简洁易用。
● 异步支持: okhttp 提供了异步调用的支持,而 apache httpclient 和 resttemplate 需要通过额外的工作来实现异步调用。
● 与框架集成: resttemplate 与 spring 框架集成度高,更适合于 spring 项目;而 apache httpclient 和 okhttp 可以在各种项目中独立使用。
● 更新维护: okhttp 是 square 公司维护的开源项目,更新迭代较为活跃;apache httpclient 在过去曾有一段时间的停滞,但也在持续维护;而 resttemplate 在新项目中可能会被 webclient 替代,不再是 spring 官方推荐的首选。
综上所述,选择合适的 http 客户端库取决于项目需求、性能要求、对框架集成的需求以及个人偏好等因素。
httpclient:
- apache httpclient:
○ 成熟稳定: apache httpclient 是 apache 软件基金会的一个项目,经过多年的发展,已经非常成熟和稳定。
○ 灵活性: 提供了丰富的配置选项和扩展点,可以灵活地定制和扩展功能。
○ 线程安全: httpclient 的实例是线程安全的,可以在多线程环境中共享使用。
○ 相对庞大: 相对于其他库来说,apache httpclient 的体积较大,可能会增加应用程序的大小。
okhttp:
- square okhttp:
○ 高性能: okhttp 是一个现代化的 http 客户端,具有优秀的性能和效率。
○ 简洁易用: 提供了简洁的 api 设计,易于学习和使用。
○ 支持 http/2: 支持 http/2,可以实现多路复用,提高并发性能。
○ 轻量级: okhttp 的体积相对较小,对应用程序的大小影响较小。
resttemplate:
- spring resttemplate:
○ 与 spring 集成: resttemplate 是 spring 框架提供的一个 http 客户端,与 spring 生态集成度高。
○ 便捷的 restful 支持: 提供了便捷的 restful 风格的 api 调用支持,如 http 方法映射、请求和响应消息转换等。
○ 同步阻塞: resttemplate 是一个同步阻塞的 http 客户端,对于高并发场景可能性能较差。
○ 可能过时: 随着 spring 5 推出的 webclient,resttemplate 在新项目中可能会逐渐被 webclient 替代。
httpclient
apache httpclient 是一个用于执行 http 请求的开源 java 库。它提供了丰富的功能和灵活的接口,可以用来发送 http 请求并处理 http 响应。
httpclient 是apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快
功能特点:
- 支持多种 http 方法: apache httpclient 支持 get、post、put、delete 等常见的 http 方法,以及任意自定义的 http 方法。
- 支持 https: httpclient 支持使用 ssl/tls 加密协议进行 https 请求,并可以自定义 ssl/tls 配置。
- 连接管理: httpclient 提供了连接池管理机制,可以有效地管理 http 连接,减少连接建立的开销。
- 请求和响应拦截器: httpclient 允许用户定义请求和响应的拦截器,可以在请求发送前或响应返回后对请求和响应进行处理。
- 自定义请求头和请求参数: httpclient 允许用户自定义请求头和请求参数,可以灵活地设置 http 请求的各种参数。
- 重定向处理: httpclient 可以自动处理 http 请求的重定向,并且允许用户配置重定向策略。
- cookie 管理: httpclient 支持自动管理 http cookie,可以处理 cookie 的存储、发送和接收。
- 代理支持: httpclient 可以配置使用代理服务器进行 http 请求。
- 认证机制: httpclient 支持多种认证机制,包括基本认证、摘要认证、oauth 等。
核心组件: - httpclient: httpclient 类是 apache httpclient 的核心类,用于执行 http 请求并处理 http 响应。
- httprequest: httprequest 接口表示一个 http 请求,包括请求方法、请求头、请求参数等信息。
- httpresponse: httpresponse 接口表示一个 http 响应,包括状态码、响应头、响应体等信息。
- httpclientbuilder: httpclientbuilder 是用于创建 httpclient 实例的构建器,可以配置 httpclient 的各种参数。
- httpentity: httpentity 接口表示一个 http 实体,包括请求体、响应体等信息。
- httpclientcontext: httpclientcontext 类表示一个 http 执行上下文,包括请求的上下文信息、连接状态等。
httpclient 是apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快。
package org.example;
import lombok.sneakythrows;
import lombok.extern.slf4j.slf4j;
import org.apache.http.header;
import org.apache.http.httpentity;
import org.apache.http.httpresponse;
import org.apache.http.namevaluepair;
import org.apache.http.client.config.requestconfig;
import org.apache.http.client.entity.urlencodedformentity;
import org.apache.http.client.methods.closeablehttpresponse;
import org.apache.http.client.methods.httpget;
import org.apache.http.client.methods.httppost;
import org.apache.http.client.methods.httprequestbase;
import org.apache.http.client.utils.uribuilder;
import org.apache.http.concurrent.futurecallback;
import org.apache.http.entity.bytearrayentity;
import org.apache.http.entity.contenttype;
import org.apache.http.entity.stringentity;
import org.apache.http.entity.mime.multipartentitybuilder;
import org.apache.http.impl.client.closeablehttpclient;
import org.apache.http.impl.client.defaulthttprequestretryhandler;
import org.apache.http.impl.client.httpclientbuilder;
import org.apache.http.impl.nio.client.closeablehttpasyncclient;
import org.apache.http.impl.nio.client.httpasyncclients;
import org.apache.http.message.basicnamevaluepair;
import org.apache.http.util.entityutils;
import java.io.*;
import java.net.uri;
import java.net.urlencoder;
import java.nio.charset.standardcharsets;
import java.util.arraylist;
import java.util.hashmap;
import java.util.list;
import java.util.map;
import java.util.zip.gzipinputstream;
import java.util.zip.gzipoutputstream;
/**
* @desc httpclient工具类
* @author liangliang
* @date 2019/3/11 13:23
*/
@slf4j
public class httpclientutil {
/**
* httpclient基础配置信息
*/
private static final requestconfig requestconfig = requestconfig.custom()
// 设置连接超时时间(单位毫秒)
.setconnecttimeout(2000)
// 设置请求超时时间(单位毫秒)
.setconnectionrequesttimeout(2000)
// socket读写超时时间(单位毫秒)
.setsockettimeout(1000)
// 设置是否允许重定向(默认为true)
.setredirectsenabled(true)
//是否启用内容压缩,默认true
.setcontentcompressionenabled(true)
.build();
/**
* 获得http客户端
*/
private static final closeablehttpclient http_client = httpclientbuilder.create()
.setretryhandler(new defaulthttprequestretryhandler()) //失败重试,默认3次
.build();
/**
* 异步http客户端
*/
private static final closeablehttpasyncclient http_async_client = httpasyncclients.custom()
.setdefaultrequestconfig(requestconfig)
.build();
/**
* @desc 异步请求
* @param httprequestbase
* @author liangliang
* @date 2019/3/11 13:23
*/
private static void executeasync(httprequestbase httprequestbase) {
http_async_client.start();
http_async_client.execute(httprequestbase, new futurecallback<httpresponse>() {
@sneakythrows
@override
public void completed(httpresponse httpresponse) {
log.info("thread id is : {}" ,thread.currentthread().getid());
stringbuffer stringbuffer = new stringbuffer();
for (header header : httprequestbase.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("请求头信息: {}", stringbuffer.tostring());
string responseresult = null;
httpentity responseentity = httpresponse.getentity();
log.info("响应状态为:{}", httpresponse.getstatusline());
if (responseentity != null) {
responseresult = entityutils.tostring(responseentity, standardcharsets.utf_8);
log.info("响应内容为:{}",responseresult);
}
stringbuffer = new stringbuffer();
for (header header : httpresponse.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("响应头信息: {}", stringbuffer.tostring()));
}
@override
public void failed(exception e) {
log.info("thread id is : {}",thread.currentthread().getid());
log.error("exception responseresult:{}", e);
e.printstacktrace();
}
@override
public void cancelled() {
log.info(httprequestbase.getrequestline() + " cancelled");
}
});
}
/**
* @desc string请求
* @param httprequestbase
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
private static string execute(httprequestbase httprequestbase) {
log.info("请求地址: {},请求类型: {}", httprequestbase.geturi().tostring(,httprequestbase.getmethod()));
stringbuffer stringbuffer = new stringbuffer();
for (header header : httprequestbase.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("请求头信息: {}", stringbuffer.tostring());
log.info("请求参数: {}", httprequestbase.geturi().getquery());
string responseresult = null;
// 响应模型
closeablehttpresponse response = null;
try {
// 将上面的配置信息 运用到这个get请求里
httprequestbase.setconfig(requestconfig);
long t1 = system.nanotime();//请求发起的时间
response = http_client.execute(httprequestbase);
// 从响应模型中获取响应实体
httpentity responseentity = response.getentity();
log.info("响应状态为:{}",response.getstatusline());
long t2 = system.nanotime();//收到响应的时间
if (responseentity != null) {
responseresult = entityutils.tostring(responseentity, standardcharsets.utf_8);
log.info("响应内容为:{}",responseresult);
}
stringbuffer = new stringbuffer();
for (header header : response.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("响应头信息: {}", stringbuffer.tostring());
log.info("执行时间: {}", (t2 - t1));
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (ioexception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
}
return responseresult;
}
/**
* @desc byte[]请求
* @param httprequestbase
* @return byte[]
* @author liangliang
* @date 2019/3/11 13:23
*/
private static byte[] executebytes(httprequestbase httprequestbase) {
log.info("请求地址: {},请求类型: {}", httprequestbase.geturi().tostring(,httprequestbase.getmethod()));
stringbuffer stringbuffer = new stringbuffer();
for (header header : httprequestbase.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("请求头信息: {}", stringbuffer.tostring());
log.info("请求参数: {}", httprequestbase.geturi().getquery());
byte[] bytes = null;
// 响应模型
closeablehttpresponse response = null;
try {
// 将上面的配置信息 运用到这个get请求里
httprequestbase.setconfig(requestconfig);
long t1 = system.nanotime();//请求发起的时间
response = http_client.execute(httprequestbase);
// 从响应模型中获取响应实体
httpentity responseentity = response.getentity();
log.info("响应状态为:{}", response.getstatusline());
long t2 = system.nanotime();//收到响应的时间
if (responseentity != null) {
bytes = entityutils.tobytearray(responseentity);
//判断是否需要解压,即服务器返回是否经过了gzip压缩--start
header responseheader = response.getfirstheader("content-encoding");
if (responseheader != null && responseheader.getvalue().contains("gzip")) {
gzipinputstream gzipinputstream = null;
bytearrayoutputstream out = null;
try {
gzipinputstream = new gzipinputstream(new bytearrayinputstream(bytes));
out = new bytearrayoutputstream();
byte[] buffer = new byte[1024];
int offset = -1;
while ((offset = gzipinputstream.read(buffer)) != -1) {
out.write(buffer, 0, offset);
}
bytes = out.tobytearray();
} catch (ioexception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
} finally {
try {
gzipinputstream.close();
out.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
}
//判断是否需要解压,即服务器返回是否经过了gzip压缩--end
log.info("响应byte长度:{}", bytes.length);
}
stringbuffer = new stringbuffer();
for (header header : response.getallheaders()) {
stringbuffer.append(header.tostring()).append(",");
}
log.info("响应头信息: {}", stringbuffer.tostring());
log.info("执行时间: {}", (t2 - t1));
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (ioexception e) {
e.printstacktrace();
}
}
return bytes;
}
/**
* @desc get请求
* @param url
* @return tring
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string get(string url) {
return get(url, new hashmap<>());
}
/**
* @desc get请求
* @param url, params
* @return tring
* @author mal
* @date 2019/3/11 13:23
*/
public static string get(string url, map<string, object> params) {
httpget httpget = null;
list<namevaluepair> list = new arraylist<>();
for (string key : params.keyset()) {
list.add(new basicnamevaluepair(key, params.get(key).tostring()));
}
// 由客户端执行(发送)get请求
try {
uri uri = new uribuilder(url).addparameters(list).build();
// 创建get请求
httpget = new httpget(uri);
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return execute(httpget);
}
/**
* @desc get请求
* @param url, params
* @return byte[]
* @author liangliang
* @date 2019/3/11 13:23
*/
public static byte[] getbytes(string url, map<string, object> params) {
httpget httpget = null;
list<namevaluepair> list = new arraylist<>();
for (string key : params.keyset()) {
list.add(new basicnamevaluepair(key, params.get(key).tostring()));
}
// 由客户端执行(发送)get请求
try {
uri uri = new uribuilder(url).addparameters(list).build();
// 创建get请求
httpget = new httpget(uri);
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return executebytes(httpget);
}
/**
* @desc post请求
* @param url
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string post(string url) {
return post(url, new hashmap<>());
}
/**
* @desc post请求
* @param url, params
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string post(string url, map<string, object> params) {
httppost httppost = null;
list<namevaluepair> list = new arraylist<>();
for (string key : params.keyset()) {
list.add(new basicnamevaluepair(key, params.get(key).tostring()));
}
try {
uri uri = new uribuilder(url).addparameters(list).build();
httppost = new httppost(uri);
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return execute(httppost);
}
/**
* @desc post请求
* @param url, params
* @return byte[]
* @author liangliang
* @date 2019/3/11 13:23
*/
public static byte[] postbytes(string url, map<string, object> params) {
httppost httppost = null;
list<namevaluepair> list = new arraylist<>();
for (string key : params.keyset()) {
list.add(new basicnamevaluepair(key, params.get(key).tostring()));
}
try {
uri uri = new uribuilder(url).addparameters(list).build();
httppost = new httppost(uri);
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return executebytes(httppost);
}
/**
* @desc post请求
* @param url, json
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postjson(string url, string json) {
return postjson(url, json, false);
}
/**
* @desc post请求
* @param url, json, gzip
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postjson(string url, string json, boolean gzip) {
httppost httppost = null;
try {
uri uri = new uribuilder(url).build();
httppost = new httppost(uri);
// post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中
httppost.setheader("content-type", "application/json;charset=utf8");
if (gzip) {
httppost.setheader("content-encoding", "gzip");
bytearrayoutputstream originalcontent = new bytearrayoutputstream();
originalcontent.write(json.getbytes(standardcharsets.utf_8));
bytearrayoutputstream baos = new bytearrayoutputstream();
gzipoutputstream gzipout = new gzipoutputstream(baos);
originalcontent.writeto(gzipout);
gzipout.finish();
httppost.setentity(new bytearrayentity(baos
.tobytearray(), contenttype.create("text/plain", "utf-8")));
} else {
stringentity entity = new stringentity(json, "utf-8");
httppost.setentity(entity);
}
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return execute(httppost);
}
/**
* @desc post请求byte流
* @param url, bytes
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postinputbytes(string url, byte[] bytes) {
return postinputbytes(url, bytes, false);
}
/**
* @desc post请求byte流
* @param url, bytes, gzip
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postinputbytes(string url, byte[] bytes, boolean gzip) {
httppost httppost = null;
try {
uri uri = new uribuilder(url).build();
httppost = new httppost(uri);
// post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中
if (gzip) {
httppost.setheader("content-encoding", "gzip");
bytearrayoutputstream originalcontent = new bytearrayoutputstream();
originalcontent.write(bytes);
bytearrayoutputstream baos = new bytearrayoutputstream();
gzipoutputstream gzipout = new gzipoutputstream(baos);
originalcontent.writeto(gzipout);
gzipout.finish();
httppost.setentity(new bytearrayentity(baos
.tobytearray(), contenttype.create("text/plain", "utf-8")));
} else {
bytearrayentity entity = new bytearrayentity(bytes, contenttype.create("text/plain", "utf-8"));
httppost.setentity(entity);
}
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return execute(httppost);
}
/**
* @desc post请求流
* @param url, is
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postinputstream(string url, inputstream is) {
return postinputstream(url, is, false);
}
/**
* @desc post请求流
* @param url, is, gzip
* @return string
* @author liangliang
* @date 2019/3/11 13:23
*/
public static string postinputstream(string url, inputstream is, boolean gzip) {
bytearrayoutputstream bytearrayoutputstream = new bytearrayoutputstream();
byte[] buffer = new byte[1024];
int ch;
byte[] bytes = null;
try {
while ((ch = is.read(buffer)) != -1) {
bytearrayoutputstream.write(buffer, 0, ch);
}
bytes = bytearrayoutputstream.tobytearray();
bytearrayoutputstream.close();
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return postinputbytes(url, bytes, gzip);
}
/**
* @desc post请求文件
* @param url, files
* @return string
* @author zhangh
* @date 2019/3/11 13:23
*/
public static string postfile(string url, file[] files) {
return postfile(url, new hashmap<>(), files);
}
/**
* @desc post请求文件
* @param url, params, files
* @return string
* @author zhangh
* @date 2019/3/11 13:23
*/
public static string postfile(string url, map<string, object> params, file[] files) {
httppost httppost = null;
try {
uri uri = new uribuilder(url).build();
httppost = new httppost(uri);
multipartentitybuilder multipartentitybuilder = multipartentitybuilder.create();
string fileskey = "files";
for (file file : files) {
//multipartentitybuilder.addpart(fileskey,new filebody(file)); //与下面的语句作用相同
//multipartentitybuilder.addbinarybody(fileskey, file);
// 防止服务端收到的文件名乱码。 我们这里可以先将文件名urlencode,然后服务端拿到文件名时在urldecode。就能避免乱码问题。
// 文件名其实是放在请求头的content-disposition里面进行传输的,如其值为form-data; name="files"; filename="头像.jpg"
multipartentitybuilder.addbinarybody(fileskey, file, contenttype.default_binary, urlencoder.encode(file.getname(), "utf-8"));
}
// 其它参数(注:自定义contenttype,设置utf-8是为了防止服务端拿到的参数出现乱码)
contenttype contenttype = contenttype.create("text/plain", standardcharsets.utf_8);
for (string key : params.keyset()) {
multipartentitybuilder.addtextbody(key, params.get(key).tostring(), contenttype);
}
httpentity entity = multipartentitybuilder.build();
// post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中
httppost.setentity(entity);
} catch (exception e) {
log.error("exception responseresult:{}", e.getmassage());
e.printstacktrace();
}
return execute(httppost);
}
}
okhttp
高效的http客户端,它能允许同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力,透明的gzip压缩减少响应数据的大小;缓存响应内容。
okhttp 是一个现代化的 http 客户端库,由 square 公司开发并维护,用于在 android 和 java 应用程序中发送 http 请求和接收 http 响应。它具有以下特点和优势:
高性能: okhttp 使用了连接池、复用连接、异步请求等技术,可以实现高效的 http 请求和响应处理,性能优秀。
支持 http/2: okhttp 支持 http/2,能够实现多路复用,提高了网络请求的并发效率。
简洁易用的 api: okhttp 提供了简洁易用的 api 设计,使用起来非常方便,易于学习和使用。
丰富的功能: okhttp 提供了丰富的功能,包括请求和响应的拦截、重定向、gzip 压缩、连接池管理等,可以满足各种复杂的应用场景需求。
灵活性: okhttp 提供了丰富的配置选项和扩展点,可以灵活地定制和扩展功能,满足各种特定需求。
支持同步和异步请求: okhttp 支持同步和异步请求,可以根据需求选择合适的方式进行网络请求。
轻量级: okhttp 的体积相对较小,对应用程序的大小影响较小,适合于移动端应用和对包大小敏感的项目。
持续更新和维护: okhttp 是由 square 公司维护的开源项目,更新迭代较为活跃,能够及时修复 bug 和添加新功能。
1、高效的http客户端,它能允许同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力,透明的gzip压缩减少响应数据的大小;缓存响应内容。
2、okhttp 对http和https都有良好的支持。
3、okhttp 对大数据量的网络请求支持非常好。
import okhttp3.*;
import org.apache.commons.lang3.exception.exceptionutils;
import java.io.file;
import java.util.iterator;
import java.util.map;
@slf4j
public class okhttputil{
private static okhttpclient okhttpclient;
@autowired
public okhttputil(okhttpclient okhttpclient) {
okhttputil.okhttpclient= okhttpclient;
}
/**
* get
* @param url 请求的url
* @param param 请求的参数
* @return
*/
public static string get(string url, map<string, string> param) {
string responsebody = "";
stringbuffer sb = new stringbuffer(url);
if (param!= null && param.keyset().size() > 0) {
boolean firstflag = true;
iterator iterator = param.entryset().iterator();
while (iterator.hasnext()) {
map.entry entry = (map.entry<string, string>) iterator.next();
if (firstflag) {
sb.append("?" + entry.getkey() + "=" + entry.getvalue());
firstflag = false;
} else {
sb.append("&" + entry.getkey() + "=" + entry.getvalue());
}
}
}
request request = new request.builder()
.url(sb.tostring())
.build();
response response = null;
try {
response = okhttpclient.newcall(request).execute();
int status = response.code();
if (response.issuccessful()) {
return response.body().string();
}
} catch (exception e) {
log.error("okhttp3 post exception:{}", e.getmessage());
} finally {
if (response != null) {
response.close();
}
}
return responsebody;
}
/**
* post
*
* @param url 请求的url
* @param params post form 提交的参数
* @return
*/
public static string post(string url, map<string, string> params) {
string responsebody = "";
formbody.builder builder = new formbody.builder();
//添加参数
if (params != null && params.keyset().size() > 0) {
for (string key : params.keyset()) {
builder.add(key, params.get(key));
}
}
request request = new request.builder()
.url(url)
.post(builder.build())
.build();
response response = null;
try {
response = okhttpclient.newcall(request).execute();
int status = response.code();
if (response.issuccessful()) {
return response.body().string();
}
} catch (exception e) {
log.error("okhttp3 post exception:{}", e.getmessage());
} finally {
if (response != null) {
response.close();
}
}
return responsebody;
}
/**
* get
* @param url 请求的url
* @param param 请求的参数
* @return
*/
public static string getforheader(string url, map<string, string> param) {
string responsebody = "";
stringbuffer sb = new stringbuffer(url);
if (param != null && param.keyset().size() > 0) {
boolean firstflag = true;
iterator iterator = param.entryset().iterator();
while (iterator.hasnext()) {
map.entry entry = (map.entry<string, string>) iterator.next();
if (firstflag) {
sb.append("?" + entry.getkey() + "=" + entry.getvalue());
firstflag = false;
} else {
sb.append("&" + entry.getkey() + "=" + entry.getvalue());
}
}
}
request request = new request.builder()
.addheader("key", "value")
.url(sb.tostring())
.build();
response response = null;
try {
response = okhttpclient.newcall(request).execute();
int status = response.code();
if (response.issuccessful()) {
return response.body().string();
}
} catch (exception e) {
log.error("okhttp3 post exception:{}", e.getmessage());
} finally {
if (response != null) {
response.close();
}
}
return responsebody;
}
/**
* post请求发送json数据
* @param url 请求url
* @param jsonparams 请求的json
*/
public static string postjsonparams(string url, string jsonparams) {
string responsebody = "";
requestbody requestbody = requestbody.create(mediatype.parse("application/json; charset=utf-8"), jsonparams);
request request = new request.builder()
.url(url)
.post(requestbody)
.build();
response response = null;
try {
response = okhttpclient.newcall(request).execute();
int status = response.code();
if (response.issuccessful()) {
return response.body().string();
}
} catch (exception e) {
log.error("okhttp3 post exception:{}", e.getmessage());
} finally {
if (response != null) {
response.close();
}
}
return responsebody;
}
/**
* post请求发送xml类型数据
* @param url 请求url
* @param xml 请求的xml
*/
public static string postxmlparams(string url, string xml) {
string responsebody = "";
requestbody requestbody = requestbody.create(mediatype.parse("application/xml; charset=utf-8"), xml);
request request = new request.builder()
.url(url)
.post(requestbody)
.build();
response response = null;
try {
response = okhttpclient.newcall(request).execute();
int status = response.code();
if (response.issuccessful()) {
return response.body().string();
}
} catch (exception e) {
log.error("okhttp3 post exception:{}", e.getmessage());
} finally {
if (response != null) {
response.close();
}
}
return responsebody;
}
}
resttemplate
resttemplate 是 spring 框架提供的一个用于进行 http 请求的模板类,它简化了在 java 中进行 http 请求的操作。resttemplate 提供了丰富的方法来发送 http 请求,并且支持多种 http 请求方法(如 get、post、put、delete 等),以及各种数据格式(如 json、xml 等)的处理。
resttemplate 是由spring提供的一个http请求工具。比传统的apache和httpclient便捷许多,能够大大提高客户端的编写效率。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
在微服务中的使用
1、第三方服务调用,个人常用 resttemplate, 这里resttemplate未未进行封装,直接使用其方法。
2、微服务间调用,个人使用feign,同时使用okhttp替换feign中默认的httpclient。
feign在默认情况下使用的是jdk原生的urlconnection发送http请求,没有连接池,但是对每个地址会保持一个长连接,即利用http的persistence connection 。 我们可以用http client 或 okhttp 替换feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。
特点和优势:
- 与 spring 集成: resttemplate 是 spring 框架的一部分,与 spring 生态完美集成,可以轻松在 spring 项目中使用。
- 简化 http 请求: resttemplate 封装了发送 http 请求的底层细节,使得发送 http 请求变得简单和方便。
- restful 支持: resttemplate 提供了便捷的 restful 风格的 api 调用支持,可以方便地进行资源的增删改查操作。
- 丰富的方法: resttemplate 提供了多种方法来发送不同类型的 http 请求,包括 getforobject()、postforobject()、exchange() 等,以及一系列便捷的方法用于设置请求参数、请求头等。
- 支持数据转换: resttemplate 支持自动将请求和响应的数据转换为 java 对象,可以通过消息转换器实现 json、xml 等格式的数据转换。
- 同步阻塞: resttemplate 是一个同步阻塞的 http 客户端,发送请求后会阻塞当前线程直到收到响应或超时。
- 异常处理: resttemplate 提供了异常处理机制,可以捕获和处理请求过程中可能出现的异常。
resttemplate 是由spring提供的一个http请求工具。比传统的apache和httpclient便捷许多,能够大大提高客户端的编写效率。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
在微服务中的使用
1、第三方服务调用,个人常用 resttemplate, 这里resttemplate未未进行封装,直接使用其方法。
2、微服务间调用,个人使用feign,同时使用okhttp替换feign中默认的httpclient。
feign在默认情况下使用的是jdk原生的urlconnection发送http请求,没有连接池,但是对每个地址会保持一个长连接,即利用http的persistence connection 。 我们可以用http client 或 okhttp 替换feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。
resttemplate 是由spring提供的一个http请求工具。比传统的apache和httpclient便捷许多,能够大大提高客户端的编写效率。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
1、spring 提供的用于访问rest服务的客户端, resttemplate 提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。
2、面向对 restful web 服务调用的功能。
在微服务中的使用
1、第三方服务调用,个人常用 resttemplate, 这里resttemplate未未进行封装,直接使用其方法。
2、微服务间调用,个人使用feign,同时使用okhttp替换feign中默认的httpclient。
feign在默认情况下使用的是jdk原生的urlconnection发送http请求,没有连接池,但是对每个地址会保持一个长连接,即利用http的persistence connection 。 我们可以用http client 或 okhttp 替换feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。
springcloud 1.x
<!-- 使用apache httpclient替换feign原生httpclient -->
<dependency>
<groupid>org.apache.httpcomponents</groupid>
<artifactid>httpclient</artifactid>
</dependency>
<dependency>
<groupid>com.netflix.feign</groupid>
<artifactid>feign-httpclient</artifactid>
<version>${feign-httpclient}</version>
</dependency>
application.properties中添加:
feign.httpclient.enabled=true
<!-- 使用okhttp替换feign原生httpclient -->
<dependency>
<groupid>io.github.openfeign</groupid>
<artifactid>feign-okhttp</artifactid>
<version>10.2.0</version>
</dependency>
springcolud 2.x
<!-- 使用okhttp替换openfeign原生httpclient -->
<dependency>
<groupid>com.squareup.okhttp3</groupid>
<artifactid>okhttp</artifactid>
<version>3.10.0</version>
</dependency>
application.properties中添加:
feign.okhttp.enabled=true
发表评论