本文主要以代码的形式讲解如下四种http客户端连接方式的基础使用
- 通过JDK网络类HttpURLConnection
- 通过common封装好的httpclient
- 通过Apache封装好的CloseableHttpClient
- 通过OkHttpClient
关于spring中常用的RestTemplate会在后续文章中单独设立一个章节来详细讲述其原理和项目中的使用情况,因此本文不开展讲述。官网地址如下:
此外插播一条关于本公众号的简讯,本公众号秉承本人和订阅者共同学习的态度进行创作,后续规划会维持一年左右的Java整个生态知识体系的更新,从Java基础-Java框架-Java分布式微服务-Java常用的中间件技术-devops-Java相关云技术,等都会按顺序依次推出更新,由于作者知识水平有限,内容不一定充实和完全正确,望大家批评指正,互相学习。
1、首先定义http请求中常用的请求方式
package com.liziba.http.utils;import java.util.Arrays;import java.util.HashMap;import java.util.Map;/** * @auther LiZiBa * @date 2020/12/11 23:44 * @description: Http方式 **/public enum HttpMethod { GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH, TRACE; private static final Map mappings; public boolean matches(String method) { return this == resolve(method); } public static HttpMethod resolve(String method) { return ((method != null) ? (HttpMethod)mappings.get(method) : null); } static { mappings = new HashMap<>(8); HttpMethod[] arrayOfHttpMethod = values(); Arrays.asList(arrayOfHttpMethod).forEach(m -> { mappings.put(m.name(), m); }); }}
2、通过JDK网络类HttpURLConnection
package com.liziba.http.utils;import com.sun.istack.internal.Nullable;import java.io.*;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;/** * @auther LiZiBa * @date 2020/12/11 23:40 * @description: 通过JDK网络类java.net.HttpURLConnection类实现调用第三方Http接口 **/public class HttpURLConnectionUtil { /** * HTTP GET请求 * @param httpUrl 请求连接地址 * @return 返回请求结果 */ public static String doGet(String httpUrl) { HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; StringBuffer sb = new StringBuffer(); try { URL url = new URL(httpUrl); connection = (HttpURLConnection) url.openConnection(); // 设置请求方式 connection.setRequestMethod(HttpMethod.GET.name()); // 设置超时时间 毫秒 connection.setConnectTimeout(60000); // 开始连接 connection.connect(); // 相应结果为200则获取相应数据 if(connection.getResponseCode() == 200) { is = connection.getInputStream(); if(null != br) { // 缓冲字符流读取数据 br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String line = null; while(null != (line = br.readLine()) ) { sb.append(line); } } } }catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } // 关闭远程连接 connection.disconnect(); } return sb.toString(); } /** * HTTP POST请求 * @param httpUrl 请求连接地址 * @param param 请求参数 * @return 接口返回结果 */ public static String doPost(String httpUrl, @Nullable String param) { HttpURLConnection connection = null; InputStream is = null; OutputStream os = null; BufferedReader br = null; StringBuffer sb = new StringBuffer(); try { URL url = new URL(httpUrl); // 建立连接 connection = (HttpURLConnection) url.openConnection(); // 设置请求方式 connection.setRequestMethod(HttpMethod.POST.name()); // 设置请求连接超时时间 connection.setConnectTimeout(60000); // 设置读取超时时间 connection.setReadTimeout(15000); // setDoInput设置是否可以从HttpURLConnection读取数据 connection.setDoInput(true); // setDoOutput设置是否可以从HttpURLConnection输出数据 connection.setDoOutput(true); // 设置通用请求属性 connection.setRequestProperty("accept", "/"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0(compatible; MSIE 6.0; Windows NT 5.1; SV1)"); connection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); // 设置请求参数 if(null != param && !"".equals(param)) { os = connection.getOutputStream(); os.write(param.getBytes("UTF-8")); } // 开启连接 connection.connect(); // 读取数据 if(connection.getResponseCode() == 200) { is = connection.getInputStream(); if(null != is) { br = new BufferedReader(new InputStreamReader(is, "GBK"));// UTF-8 String readLine = null; while(null != (readLine = br.readLine())) { sb.append(readLine); sb.append("\r\n"); } } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { // 关闭连接流 if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } // 关闭连接 connection.disconnect(); } return sb.toString(); }}
3、通过common封装好的httpclient
package com.liziba.http.utils;import com.alibaba.fastjson.JSONObject;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;import org.apache.commons.httpclient.Header;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpStatus;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.PostMethod;import org.apache.commons.httpclient.params.HttpMethodParams;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Arrays;/** * @auther LiZiBa * @date 2020/12/12 9:15 * @description: **/public class HttpClientUtil { public static String doGet(String httpUrl, String charset) { // 1、创建HttpClient对象 HttpClient httpClient = new HttpClient(); // 设置连接超时时间为6秒 httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(6000); // 2、创建GetMethod对象并设置参数 GetMethod getMethod = new GetMethod(httpUrl); // 设置http get请求超时时间为6秒 getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 6000); // 设置默认请求重试次数,DefaultHttpMethodRetryHandler默认为3次 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); BufferedReader bufferedReader = null; StringBuffer response = new StringBuffer(); // 3、执行请求 try { // 4、判断请求返回状态码 int statusCode = httpClient.executeMethod(getMethod); // 请求错误简单输出错误 if(statusCode != HttpStatus.SC_OK) { System.err.println(String.format("请求错误:%s", getMethod.getStatusLine())); } // 5、处理请求响应内容 // http 响应头打印 Header[] responseHeaders = getMethod.getResponseHeaders(); Arrays.asList(responseHeaders).forEach(h -> { System.out.println(h.getName() + "-" + h.getValue()); }); // http 响应体内容 InputStream is = getMethod.getResponseBodyAsStream(); bufferedReader = new BufferedReader(new InputStreamReader(is, charset)); String readLine = null; while(null != (readLine = bufferedReader.readLine())) { response.append(readLine); response.append("\r\n"); } System.out.println("请求内容 response:"+ response.toString()); } catch (IOException e) { e.printStackTrace(); } finally { // 释放连接 getMethod.releaseConnection(); } return response.toString(); } /** * HttpClient 请求 * @param httpUrl * @param charset * @return */ public static String doPost(String httpUrl, String charset, JSONObject json) { HttpClient httpClient = new HttpClient(); // http post 请求 PostMethod postMethod = new PostMethod(httpUrl); // 设置请求头通用参数 postMethod.addRequestHeader("accept", "/"); postMethod.addRequestHeader("connection", "Keep-Alive"); postMethod.addRequestHeader("Content-Type", "application/json;charset=" + charset); postMethod.addRequestHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"); // 演示添加 请求参数 postMethod.addParameter("param", json.getString("param")); BufferedReader bufferedReader = null; StringBuffer response = new StringBuffer(); try { int statusCode = httpClient.executeMethod(postMethod); // 只处理正确内容,其余可自行补充 if(statusCode == HttpStatus.SC_OK) { // http 响应体内容 InputStream is = postMethod.getResponseBodyAsStream(); bufferedReader = new BufferedReader(new InputStreamReader(is, charset)); String readLine = null; while(null != (readLine = bufferedReader.readLine())) { response.append(readLine); response.append("\r\n"); } System.out.println("响应内容 response:" + response.toString()); } } catch (IOException e) { e.printStackTrace(); } finally { // 释放连接 postMethod.releaseConnection(); } return response.toString(); }}
4、通过Apache封装好的CloseableHttpClient
package com.liziba.http.util;import com.alibaba.fastjson.JSONObject;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.util.EntityUtils;import java.io.IOException;import java.io.UnsupportedEncodingException;/** * @auther LiZiBa * @date 2020/12/12 10:44 * @description: **/public class CloseableHttpClientUtil { private static CloseableHttpClient httpClient = null; /** * get 请求接口 * @param url 请求地址 * @param token 请求token * @return */ public static String doGet(String url, String token) { httpClient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(url); if (null != token && !"".equals(token)) { token = getToken(); } // 后端接口或者网关层自定义token验证key httpGet.addHeader("gateway_auth_token", token); httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"); try { HttpResponse response = httpClient.execute(httpGet); // 连接正常返回 if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity); return result; } } catch (IOException e) { e.printStackTrace(); } finally { if (null != httpClient) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * post 请求接口 * @param url 请求地址 * @param token 请求token * @param param 请求参数 * @return */ private static String doPost(String url, String token, JSONObject param) { httpClient = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost(url); if (null != token && !"".equals(token)) { token = getToken(); } // 后端接口或者网关层自定义token验证key httpPost.addHeader("gateway_auth_token", token); httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"); try { StringEntity se = new StringEntity(param.toString()); se.setContentEncoding("UTF-8"); // 设置ContentType以便于传输JSON数据 se.setContentType("application/x-www-form-urlencoded"); // 设置请求参数 httpPost.setEntity(se); // 执行请求 HttpResponse response = httpClient.execute(httpPost); if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity); return result; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(null != httpClient) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 指定地址获取token * @return */ private static String getToken() { String token = ""; JSONObject object = new JSONObject(); object.put("appId", "appId"); object.put("secretKey", "secretKey"); if (null == httpClient) { httpClient = HttpClientBuilder.create().build(); } HttpPost httpPost = new HttpPost("http://localhost:8080/oig/getToken"); httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"); try { StringEntity se = new StringEntity(object.toString()); // 设置编码格式 se.setContentEncoding("UTF-8"); // 设置ContentType以便于传输JSON数据 se.setContentType("application/x-www-form-urlencoded"); // 设置请求参数 httpPost.setEntity(se); // 执行请求 HttpResponse response = httpClient.execute(httpPost); // 根据接口规范解析自定义返回结果 JSONObject result = JSONObject.parseObject(String.valueOf(response)); // 判断是否包含token if(result.containsKey("token")) { token = result.getString("token"); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return token; }}
5、通过OkHttpClient
package com.liziba.http.util;import okhttp3.*;import java.io.*;import java.util.concurrent.TimeUnit;/** * @auther LiZiBa * @date 2020/12/12 12:30 * @description: **/public class OkHttpUtil { /** * 同步get方式请求 * @param url 请求接口地址 * @return */ public static void syncGet(String url) { // 1、创建一个OkHttpClient对象 OkHttpClient client = new OkHttpClient(); // 2、创建一个请求 Request request = new Request.Builder().url(url).build(); InputStream is = null; BufferedReader br = null; StringBuffer result = null; try { // 3、返回实体 Response response = client.newCall(request).execute(); if (response.isSuccessful()){ // 小数据量 1M以下// temp = response.body().string(); // 返回数据较大 is = response.body().byteStream(); if(null != is) { String temp = null; br = new BufferedReader(new InputStreamReader(is, "UTF-8")); while (null != (temp = br.readLine())) { result.append(temp); result.append("/r/n"); } } } else { System.err.println("请求错误!"); } } catch (IOException e) { e.printStackTrace(); } finally { if(null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * get 异步请求 * @param url 请求地址 */ public static void asyncGet(String url) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); client.newCall(request).enqueue(new Callback() { // 请求失败回调 public void onFailure(Call call, IOException e) { System.err.println(e.getMessage()); } // 请求成功回调 public void onResponse(Call call, Response response) throws IOException { InputStream is = null; BufferedReader br = null; StringBuffer result = null; try{ is = response.body().byteStream(); if(null != is) { String temp = null; br = new BufferedReader(new InputStreamReader(is, "UTF-8")); while (null != (temp = br.readLine())) { result.append(temp); result.append("/r/n"); } } }catch (Exception e) { e.printStackTrace(); }finally { if(null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }); } /** * post 提交表单 * @param url 请求参数 * @param param 请求地址 */ public static void postFormParameters(String url, String param) { // 创建OkHttpClient OkHttpClient client = new OkHttpClient(); // 表单键值对 FormBody formBody = new FormBody.Builder().add("key", param).build(); // 发起请求 Request request = new Request.Builder().url(url).post(formBody).build(); // 异步回调 client.newCall(request).enqueue(new Callback() { // 错误回调 public void onFailure(Call call, IOException e) { System.err.println("错误回调..."); } // 成功回调 public void onResponse(Call call, Response response) throws IOException { System.out.println("成功回调..."); } }); } /** * post 提交字符串 * @param url */ public static void postStringParameters(String url) { MediaType mediaType = MediaType.parse("text/text;charset=utf-8"); // 创建OkHttpClient OkHttpClient client = new OkHttpClient(); // 需要提交的字符串 String key = "liziba"; Request request = new Request.Builder().url(url).post(RequestBody.create(mediaType, key)).build(); client.newCall(request).enqueue(new Callback() { // 错误回调 public void onFailure(Call call, IOException e) { System.err.println("错误回调..."); } // 成功回调 public void onResponse(Call call, Response response) throws IOException { System.out.println("成功回调..."); } }); } /** * 设置超时时间 */ public static OkHttpClient timeOutClient() { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间 .readTimeout(10, TimeUnit.SECONDS) // 设置读数据超时时间 .writeTimeout(10, TimeUnit.SECONDS) // 设置写数据超时时间 .build(); return client; } /** * 缓存设置 */ public static void cacheClient() throws Exception{ // 缓存路径 File f = new File("d:/file_cache"); // 设置缓存大小 100MB int cacheSize = 100 * 1024 * 1024; // 构建一个缓存OkHttpClient连接 OkHttpClient client =new OkHttpClient.Builder() .cache(new Cache(f.getAbsoluteFile(), cacheSize)) .build(); }}