Author: Dr sweet in it https://www.jianshu.com/p/68c30beca612
Write in front
Why did you write this article because of chatting with friends
This touched my knowledge blind spot again. First of all, I went to Baidu to learn. I searched directly based on the difference between the keywords httpclient and okhttp, and compared the performance. I did n’t find the answer I wanted. I have asked this question and I will not let you down
So compare in terms of usage, performance, timeout configuration
use
HttpClient and OkHttp are generally used to call other services. The interfaces exposed by general services are http, and the common request types of http are GET, PUT, POST, and DELETE. Therefore, the call of these request types is mainly introduced.
HttpClient introduction
Sending a request using HttpClient is mainly divided into the following steps:
Create CloseableHttpClient object or CloseableHttpAsyncClient object, the former is synchronous, the latter is asynchronous
Create Http request object
Call the execute method to execute the request, if it is an asynchronous request, you need to call the start method before executing
Create connection:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
This connection is a synchronous connection
GET request:
@Test
public void testGet() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
System.out.println(EntityUtils.toString(response.getEntity()));
}
Use HttpGet to indicate that the connection is a GET request, HttpClient calls the execute method to send the GET request
PUT request:
@Test
public void testPut() throws IOException {
String api = "/api/user";
String url = String.format("%s%s", BASE_URL, api);
HttpPut httpPut = new HttpPut(url);
UserVO userVO = UserVO.builder().name("h2t").id(16L).build();
httpPut.setHeader("Content-Type", "application/json;charset=utf8");
httpPut.setEntity(new StringEntity(JSONObject.toJSONString(userVO), "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPut);
System.out.println(EntityUtils.toString(response.getEntity()));
}
POST request:
Add object
@Test
public void testPost() throws IOException {
String api = "/api/user";
String url = String.format("%s%s", BASE_URL, api);
HttpPost httpPost = new HttpPost(url);
UserVO userVO = UserVO.builder().name("h2t2").build();
httpPost.setHeader("Content-Type", "application/json;charset=utf8");
httpPost.setEntity(new StringEntity(JSONObject.toJSONString(userVO), "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
System.out.println(EntityUtils.toString(response.getEntity()));
}
The request is a request to create an object, you need to pass in a json string
upload files
@Test
public void testUpload1() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
HttpPost httpPost = new HttpPost(url);
File file = new File("C:/Users/hetiantian/Desktop/学习/docker_practice.pdf");
FileBody fileBody = new FileBody(file);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("file", fileBody); //addPart上传文件
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
CloseableHttpResponse response = httpClient.execute(httpPost);
System.out.println(EntityUtils.toString(response.getEntity()));
}
Upload files via addPart
DELETE request:
@Test
public void testDelete() throws IOException {
String api = "/api/user/12";
String url = String.format("%s%s", BASE_URL, api);
HttpDelete httpDelete = new HttpDelete(url);
CloseableHttpResponse response = httpClient.execute(httpDelete);
System.out.println(EntityUtils.toString(response.getEntity()));
}
Cancellation requested:
@Test
public void testCancel() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig); //设置超时时间
//测试连接的取消
long begin = System.currentTimeMillis();
CloseableHttpResponse response = httpClient.execute(httpGet);
while (true) {
if (System.currentTimeMillis() - begin > 1000) {
httpGet.abort();
System.out.println("task canceled");
break;
}
}
System.out.println(EntityUtils.toString(response.getEntity()));
}
Call abort method to cancel the request execution result:
task canceled
cost 8098 msc
Disconnected from the target VM, address: '127.0.0.1:60549', transport: 'socket'
java.net.SocketException: socket closed...【省略】
OkHttp use
Sending requests using OkHttp is mainly divided into the following steps:
Create OkHttpClient object
Create Request object
Encapsulate Request object as Call
Use Call to execute synchronous or asynchronous request, call execute method to execute synchronously, call enqueue method to execute asynchronously
Create connection:
private OkHttpClient client = new OkHttpClient();
GET request:
@Test
public void testGet() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
Request request = new Request.Builder()
.url(url)
.get()
.build();
final Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
PUT request:
@Test
public void testPut() throws IOException {
String api = "/api/user";
String url = String.format("%s%s", BASE_URL, api);
//请求参数
UserVO userVO = UserVO.builder().name("h2t").id(11L).build();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
JSONObject.toJSONString(userVO));
Request request = new Request.Builder()
.url(url)
.put(requestBody)
.build();
final Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
POST request:
Add object
@Test
public void testPost() throws IOException {
String api = "/api/user";
String url = String.format("%s%s", BASE_URL, api);
//请求参数
JSONObject json = new JSONObject();
json.put("name", "hetiantian");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), String.valueOf(json));
Request request = new Request.Builder()
.url(url)
.post(requestBody) //post请求
.build();
final Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
upload files
@Test
public void testUpload() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", "docker_practice.pdf",
RequestBody.create(MediaType.parse("multipart/form-data"),
new File("C:/Users/hetiantian/Desktop/学习/docker_practice.pdf")))
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody) //默认为GET请求,可以不写
.build();
final Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
Use the addFormDataPart method to simulate the form upload file
DELETE request:
@Test
public void testDelete() throws IOException {
String url = String.format("%s%s", BASE_URL, api);
//请求参数
Request request = new Request.Builder()
.url(url)
.delete()
.build();
final Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
Cancellation requested:
@Test
public void testCancelSysnc() throws IOException {
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
Request request = new Request.Builder()
.url(url)
.get()
.build();
final Call call = client.newCall(request);
Response response = call.execute();
long start = System.currentTimeMillis();
//测试连接的取消
while (true) {
//1分钟获取不到结果就取消请求
if (System.currentTimeMillis() - start > 1000) {
call.cancel();
System.out.println("task canceled");
break;
}
}
System.out.println(response.body().string());
}
Call the cancel method to cancel the test results:
task canceled
cost 9110 msc
java.net.SocketException: socket closed...【省略】
summary
OkHttp uses the build mode to create objects more concisely, and uses the .post / .delete / .put / .get method to indicate the request type. There is no need for methods such as HttpClient to create HttpGet and HttpPost to create request types
On the dependency package, if HttpClient needs to send asynchronous requests and realize file upload, additional asynchronous request dependencies need to be introduced
<!---文件上传-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
</dependency>
<!--异步请求-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.5.3</version>
</dependency>
To cancel the request, HttpClient uses the abort method and OkHttp uses the cancel method. It is quite simple. If you are using an asynchronous client, you can call the method to cancel the request when an exception is thrown.
Timeout setting
HttpClient timeout setting:
In HttpClient 4.3+ and above, the timeout setting is set through RequestConfig
private CloseableHttpClient httpClient = HttpClientBuilder.create().build();
private RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(60 * 1000)
.setConnectTimeout(60 * 1000).build();
String api = "/api/files/1";
String url = String.format("%s%s", BASE_URL, api);
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig); //设置超时时间
The timeout is set on the request type HttpGet, not HttpClient
OkHttp timeout setting:
Set directly on OkHttp
private OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)//设置连接超时时间
.readTimeout(60, TimeUnit.SECONDS)//设置读取超时时间
.build();
summary:
If the client is in singleton mode, HttpClient is more flexible in setting timeouts, and sets different timeout times for different request types. Once OkHttp sets the timeout time, the timeout time for all request types is also determined
HttpClient and OkHttp performance comparison
test environment:
CPU six core
Memory 8G
windows10
Each test case is tested five times, excluding chance
The client connection is a singleton:
Client connection is not a singleton:
In singleton mode, the response speed of HttpClient is faster, the unit is milliseconds, the performance difference is not much different
In non-singleton mode, OkHttp performs better, and HttpClient takes more time to create a connection, because in most cases these resources will be written in singleton mode, so the test results in Figure 1 are more valuable.
to sum up
OkHttp and HttpClient are indistinguishable in performance and use, and can be selected according to the actual business.
I recommend going to my blog to read more:
1. Java JVM, collection, multithreading, new features series tutorials
2. Spring MVC, Spring Boot, Spring Cloud series of tutorials
3. Maven, Git, Eclipse, Intellij IDEA series of tool tutorials
4. The latest interview questions for Java, backend, architecture, Alibaba and other major manufacturers
Life is beautiful, see you tomorrow ~