Java OkHttp3

准备工作

Maven项目在pom文件中引入jar包

  1. <dependency>
  2. <groupId>com.squareup.okhttp3</groupId>
  3. <artifactId>okhttp</artifactId>
  4. <version>3.10.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alibaba</groupId>
  8. <artifactId>fastjson</artifactId>
  9. <version>1.2.60</version>
  10. </dependency>

引入json是因为工具类中有些地方用到了,现在通信都流行使用json传输,也少不了要这个jar包

工具类代码

  1. import com.alibaba.fastjson.JSON;
  2. import okhttp3.*;
  3. import javax.net.ssl.SSLContext;
  4. import javax.net.ssl.SSLSocketFactory;
  5. import javax.net.ssl.TrustManager;
  6. import javax.net.ssl.X509TrustManager;
  7. import java.io.IOException;
  8. import java.net.URLEncoder;
  9. import java.security.SecureRandom;
  10. import java.security.cert.X509Certificate;
  11. import java.util.LinkedHashMap;
  12. import java.util.Map;
  13. import java.util.concurrent.Semaphore;
  14. import java.util.concurrent.TimeUnit;
  15. public class OkHttpUtils {
  16. private static volatile OkHttpClient okHttpClient = null;
  17. private static volatile Semaphore semaphore = null;
  18. private Map<String, String> headerMap;
  19. private Map<String, String> paramMap;
  20. private String url;
  21. private Request.Builder request;
  22. /**
  23. * 初始化okHttpClient,并且允许https访问
  24. */
  25. private OkHttpUtils() {
  26. if (okHttpClient == null) {
  27. synchronized (OkHttpUtils.class) {
  28. if (okHttpClient == null) {
  29. TrustManager[] trustManagers = buildTrustManagers();
  30. okHttpClient = new OkHttpClient.Builder()
  31. .connectTimeout(15, TimeUnit.SECONDS)
  32. .writeTimeout(20, TimeUnit.SECONDS)
  33. .readTimeout(20, TimeUnit.SECONDS)
  34. .sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0])
  35. .hostnameVerifier((hostName, session) -> true)
  36. .retryOnConnectionFailure(true)
  37. .build();
  38. addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
  39. }
  40. }
  41. }
  42. }
  43. /**
  44. * 用于异步请求时,控制访问线程数,返回结果
  45. *
  46. * @return
  47. */
  48. private static Semaphore getSemaphoreInstance() {
  49. //只能1个线程同时访问
  50. synchronized (OkHttpUtils.class) {
  51. if (semaphore == null) {
  52. semaphore = new Semaphore(0);
  53. }
  54. }
  55. return semaphore;
  56. }
  57. /**
  58. * 创建OkHttpUtils
  59. *
  60. * @return
  61. */
  62. public static OkHttpUtils builder() {
  63. return new OkHttpUtils();
  64. }
  65. /**
  66. * 添加url
  67. *
  68. * @param url
  69. * @return
  70. */
  71. public OkHttpUtils url(String url) {
  72. this.url = url;
  73. return this;
  74. }
  75. /**
  76. * 添加参数
  77. *
  78. * @param key 参数名
  79. * @param value 参数值
  80. * @return
  81. */
  82. public OkHttpUtils addParam(String key, String value) {
  83. if (paramMap == null) {
  84. paramMap = new LinkedHashMap<>(16);
  85. }
  86. paramMap.put(key, value);
  87. return this;
  88. }
  89. /**
  90. * 添加请求头
  91. *
  92. * @param key 参数名
  93. * @param value 参数值
  94. * @return
  95. */
  96. public OkHttpUtils addHeader(String key, String value) {
  97. if (headerMap == null) {
  98. headerMap = new LinkedHashMap<>(16);
  99. }
  100. headerMap.put(key, value);
  101. return this;
  102. }
  103. /**
  104. * 初始化get方法
  105. *
  106. * @return
  107. */
  108. public OkHttpUtils get() {
  109. request = new Request.Builder().get();
  110. StringBuilder urlBuilder = new StringBuilder(url);
  111. if (paramMap != null) {
  112. urlBuilder.append("?");
  113. try {
  114. for (Map.Entry<String, String> entry : paramMap.entrySet()) {
  115. urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")).
  116. append("=").
  117. append(URLEncoder.encode(entry.getValue(), "utf-8")).
  118. append("&");
  119. }
  120. } catch (Exception e) {
  121. e.printStackTrace();
  122. }
  123. urlBuilder.deleteCharAt(urlBuilder.length() - 1);
  124. }
  125. request.url(urlBuilder.toString());
  126. return this;
  127. }
  128. /**
  129. * 初始化post方法
  130. *
  131. * @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw
  132. * false等于普通的表单提交
  133. * @return
  134. */
  135. public OkHttpUtils post(boolean isJsonPost) {
  136. RequestBody requestBody;
  137. if (isJsonPost) {
  138. String json = "";
  139. if (paramMap != null) {
  140. json = JSON.toJSONString(paramMap);
  141. }
  142. requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
  143. } else {
  144. FormBody.Builder formBody = new FormBody.Builder();
  145. if (paramMap != null) {
  146. paramMap.forEach(formBody::add);
  147. }
  148. requestBody = formBody.build();
  149. }
  150. request = new Request.Builder().post(requestBody).url(url);
  151. return this;
  152. }
  153. /**
  154. * 同步请求
  155. *
  156. * @return
  157. */
  158. public String sync() {
  159. setHeader(request);
  160. try {
  161. Response response = okHttpClient.newCall(request.build()).execute();
  162. assert response.body() != null;
  163. return response.body().string();
  164. } catch (IOException e) {
  165. e.printStackTrace();
  166. return "请求失败:" + e.getMessage();
  167. }
  168. }
  169. /**
  170. * 异步请求,有返回值
  171. */
  172. public String async() {
  173. StringBuilder buffer = new StringBuilder("");
  174. setHeader(request);
  175. okHttpClient.newCall(request.build()).enqueue(new Callback() {
  176. @Override
  177. public void onFailure(Call call, IOException e) {
  178. buffer.append("请求出错:").append(e.getMessage());
  179. }
  180. @Override
  181. public void onResponse(Call call, Response response) throws IOException {
  182. assert response.body() != null;
  183. buffer.append(response.body().string());
  184. getSemaphoreInstance().release();
  185. }
  186. });
  187. try {
  188. getSemaphoreInstance().acquire();
  189. } catch (InterruptedException e) {
  190. e.printStackTrace();
  191. }
  192. return buffer.toString();
  193. }
  194. /**
  195. * 异步请求,带有接口回调
  196. *
  197. * @param callBack
  198. */
  199. public void async(ICallBack callBack) {
  200. setHeader(request);
  201. okHttpClient.newCall(request.build()).enqueue(new Callback() {
  202. @Override
  203. public void onFailure(Call call, IOException e) {
  204. callBack.onFailure(call, e.getMessage());
  205. }
  206. @Override
  207. public void onResponse(Call call, Response response) throws IOException {
  208. assert response.body() != null;
  209. callBack.onSuccessful(call, response.body().string());
  210. }
  211. });
  212. }
  213. /**
  214. * 为request添加请求头
  215. *
  216. * @param request
  217. */
  218. private void setHeader(Request.Builder request) {
  219. if (headerMap != null) {
  220. try {
  221. for (Map.Entry<String, String> entry : headerMap.entrySet()) {
  222. request.addHeader(entry.getKey(), entry.getValue());
  223. }
  224. } catch (Exception e) {
  225. e.printStackTrace();
  226. }
  227. }
  228. }
  229. /**
  230. * 生成安全套接字工厂,用于https请求的证书跳过
  231. *
  232. * @return
  233. */
  234. private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) {
  235. SSLSocketFactory ssfFactory = null;
  236. try {
  237. SSLContext sc = SSLContext.getInstance("SSL");
  238. sc.init(null, trustAllCerts, new SecureRandom());
  239. ssfFactory = sc.getSocketFactory();
  240. } catch (Exception e) {
  241. e.printStackTrace();
  242. }
  243. return ssfFactory;
  244. }
  245. private static TrustManager[] buildTrustManagers() {
  246. return new TrustManager[]{
  247. new X509TrustManager() {
  248. @Override
  249. public void checkClientTrusted(X509Certificate[] chain, String authType) {
  250. }
  251. @Override
  252. public void checkServerTrusted(X509Certificate[] chain, String authType) {
  253. }
  254. @Override
  255. public X509Certificate[] getAcceptedIssuers() {
  256. return new X509Certificate[]{};
  257. }
  258. }
  259. };
  260. }
  261. /**
  262. * 自定义一个接口回调
  263. */
  264. public interface ICallBack {
  265. void onSuccessful(Call call, String data);
  266. void onFailure(Call call, String errorMsg);
  267. }
  268. }

使用教程

  1. public static void main(String[] args) {
  2. // get请求,方法顺序按照这种方式,切记选择post/get一定要放在倒数第二,同步或者异步倒数第一,才会正确执行
  3. OkHttpUtils.builder().url("请求地址,http/https都可以")
  4. // 有参数的话添加参数,可多个
  5. .addParam("参数名", "参数值")
  6. .addParam("参数名", "参数值")
  7. // 也可以添加多个
  8. .addHeader("Content-Type", "application/json; charset=utf-8")
  9. .get()
  10. // 可选择是同步请求还是异步请求
  11. //.async();
  12. .sync();
  13. // post请求,分为两种,一种是普通表单提交,一种是json提交
  14. OkHttpUtils.builder().url("请求地址,http/https都可以")
  15. // 有参数的话添加参数,可多个
  16. .addParam("参数名", "参数值")
  17. .addParam("参数名", "参数值")
  18. // 也可以添加多个
  19. .addHeader("Content-Type", "application/json; charset=utf-8")
  20. // 如果是true的话,会类似于postman中post提交方式的raw,用json的方式提交,不是表单
  21. // 如果是false的话传统的表单提交
  22. .post(true)
  23. .sync();
  24. // 选择异步有两个方法,一个是带回调接口,一个是直接返回结果
  25. OkHttpUtils.builder().url("")
  26. .post(false)
  27. .async();
  28. OkHttpUtils.builder().url("").post(false).async(new OkHttpUtils.ICallBack() {
  29. @Override
  30. public void onSuccessful(Call call, String data) {
  31. // 请求成功后的处理
  32. }
  33. @Override
  34. public void onFailure(Call call, String errorMsg) {
  35. // 请求失败后的处理
  36. }
  37. });
  38. }