轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)

来源:互联网 发布:linux shell编程 编辑:程序博客网 时间:2024/05/05 10:26

搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用。调用关系不清楚,结构有点混乱。所以也就萌生了自己封装HttpClient工具类的想法。要做就做最好的,本工具类支持插件式配置Header、插件式配置httpclient对象,这样就可以方便地自定义header信息、配置ssl、配置proxy等。


是不是觉得说的有点悬乎了,那就先看看调用吧:

[java] view plain copy
 print?
  1. public static void testSimple() throws HttpProcessException{  
  2.     String url = "http://www.oschina.net";  
  3.     //简单调用  
  4.     String resp = HttpClientUtil.send(url);  
  5.     System.out.println("请求结果内容长度:"+ resp.length());  
  6. }  
  7.   
  8. public static void testOne() throws HttpProcessException{         
  9.     String url = "https://sso.tgb.com:8443/cas/login";  
  10.       
  11.     //自定义HttpClient,设置超时、代理、ssl  
  12.     //HttpClient client= HCB.custom().timeout(10000).proxy("127.0.0.1", 8087).ssl().build();//采用默认方式(绕过证书验证)  
  13.     HttpClient client= HCB.custom().timeout(10000).ssl("D:\\keys\\wsriakey","tomcat").build();  
  14.       
  15.     //设置header信息  
  16.     Header[] headers=HttpHeader.custom().keepAlive("false").connection("close").contentType(Headers.APP_FORM_URLENCODED).build();  
  17.       
  18.     //执行请求  
  19.     String resp=HttpClientUtil.send(client, url, headers);  
  20.     System.out.println("请求结果如下:");  
  21.     System.out.println(resp);  
  22. }  

轻松配置了代理、自定义证书的ssl、以及各种header头信息,是不是觉得还凑合呢,那就继续看吧。


写这个工具类时,抽象了一下所有的demo,最后封装了一个最基本的方法(拆分成了2个方法了),其所有参数列表有:HttpClient对象、url(必须有)、请求方式、请求参数parasMap、header数组、编码格式encoding。


由于封装的是工具类,所以最好是无状态的,可以支持多线程的方式调用的,所以方法都是static类型的。这也是为什么要把HttpClient对象也是作为了一个参数传入而非成员变量了,而且这样也为扩展HttpClient的配置提供了便利。


因为HTTP1.1规范中定义了6种HTTP方法:GET, HEAD, POST, PUT, DELETE, TRACE 和 OPTIONS,其实还有一个PATCH,这几个方法在HttpClient中都有一个对应的类:HttpGet,HttpHead,HttpPost,HttpPut,HttpDelete,HttpTrace、HttpOptions以及HttpPatch。所有的这些类均继承了HttpRequestBase超类,故可以作为参数使用(用枚举类作为参数,用另一个方法来创建具体的请求方法对象)。


Header头信息也是作为一个重要的参数,在请求特定网站的时候需要设置不同的Header,而header又是比较繁杂的,所以这里也是作为了一个参数传入的,也是方便扩展。


使用map来作为post方式传入参数是习惯使然,不做过多的解释。


编码这个参数主要是为了为待提交的数据和反馈结果进行转码处理。


简单说一下流程:

  1. 创建请求对象request;
  2. 为request设置header信息;
  3. 判断当前请求对象是否是HttpEntityEnclosingRequestBase的子类,如果是,则支持setEntity方法,来设置参数。
  4. 执行请求,并拿到结果(同步阻塞);
  5. 获取并解码请求结果实体;
  6. 关闭链接

就是这么简单,具体来看看代码吧:

[java] view plain copy
 print?
  1. /** 
  2.  * 请求资源或服务,自定义client对象,传入请求参数,设置内容类型,并指定参数和返回数据的编码 
  3.  *  
  4.  * @param client        client对象 
  5.  * @param url           资源地址 
  6.  * @param httpMethod    请求方法 
  7.  * @param parasMap      请求参数 
  8.  * @param headers       请求头信息 
  9.  * @param encoding      编码 
  10.  * @return              返回处理结果 
  11.  * @throws HttpProcessException  
  12.  */  
  13. public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap,   
  14.             Header[] headers, String encoding) throws HttpProcessException {  
  15.     String body = "";  
  16.     try {  
  17.         //创建请求对象  
  18.         HttpRequestBase request = getRequest(url, httpMethod);  
  19.           
  20.         //设置header信息  
  21.         request.setHeaders(headers);  
  22.           
  23.         //判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)  
  24.         if(HttpEntityEnclosingRequestBase.class.isAssignableFrom(request.getClass())){  
  25.             List<NameValuePair> nvps = new ArrayList<NameValuePair>();  
  26.               
  27.             //检测url中是否存在参数  
  28.             url = Utils.checkHasParas(url, nvps);  
  29.               
  30.             //装填参数  
  31.             Utils.map2List(nvps, parasMap);  
  32.               
  33.             //设置参数到请求对象中  
  34.             ((HttpEntityEnclosingRequestBase)request).setEntity(new UrlEncodedFormEntity(nvps, encoding));  
  35.               
  36.             logger.debug("请求地址:"+url);  
  37.             if(nvps.size()>0){  
  38.                 logger.debug("请求参数:"+nvps.toString());  
  39.             }  
  40.         }else{  
  41.             int idx = url.indexOf("?");  
  42.             logger.debug("请求地址:"+url.substring(0, (idx>0 ? idx-1:url.length()-1)));  
  43.             if(idx>0){  
  44.                 logger.debug("请求参数:"+url.substring(idx+1));  
  45.             }  
  46.         }  
  47.           
  48.         //调用发送请求  
  49.         body = execute(client, request, url, encoding);  
  50.           
  51.     } catch (UnsupportedEncodingException e) {  
  52.         throw new HttpProcessException(e);  
  53.     }  
  54.     return body;  
  55. }  
  56.       
  57.   
  58. /** 
  59.  * 请求资源或服务 
  60.  *  
  61.  * @param client        client对象 
  62.  * @param request       请求对象 
  63.  * @param url           资源地址 
  64.  * @param parasMap      请求参数 
  65.  * @param encoding      编码 
  66.  * @return              返回处理结果 
  67.  * @throws HttpProcessException  
  68.  */  
  69. private static String execute(HttpClient client, HttpRequestBase request,String url, String encoding) throws HttpProcessException {  
  70.     String body = "";  
  71.     HttpResponse response =null;  
  72.     try {  
  73.           
  74.         //执行请求操作,并拿到结果(同步阻塞)  
  75.         response = client.execute(request);  
  76.           
  77.         //获取结果实体  
  78.         HttpEntity entity = response.getEntity();  
  79.           
  80.         if (entity != null) {  
  81.             //按指定编码转换结果实体为String类型  
  82.             body = EntityUtils.toString(entity, encoding);  
  83.             logger.debug(body);  
  84.         }  
  85.         EntityUtils.consume(entity);  
  86.     } catch (ParseException | IOException e) {  
  87.         throw new HttpProcessException(e);  
  88.     } finally {  
  89.         close(response);  
  90.     }  
  91.       
  92.     return body;  
  93. }  

第一个方法中,我们看到有HttpMethods类型的参数,在创建request对象时,用到了它。它是什么呢?其实只是一个枚举类:

[java] view plain copy
 print?
  1.     /** 
  2.      * 枚举HttpMethods方法 
  3.      *  
  4.      * @author arron 
  5.      * @date 2015年11月17日 下午4:45:59  
  6.      * @version 1.0 
  7.      */  
  8.     public enum HttpMethods{  
  9.           
  10.         /** 
  11.          * 求获取Request-URI所标识的资源 
  12.          */  
  13.         GET(0"GET"),   
  14.           
  15.         /** 
  16.          * 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 
  17.          * POST请求可能会导致新的资源的建立和/或已有资源的修改 
  18.          */  
  19.         POST(1"POST"),  
  20.           
  21.         /** 
  22.          * 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。 
  23.          * 这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息 
  24.          * 只获取响应信息报头 
  25.          */  
  26.         HEAD(2"HEAD"),  
  27.           
  28.         /** 
  29.          * 向指定资源位置上传其最新内容(全部更新,操作幂等) 
  30.          */  
  31.         PUT (3"PUT"),   
  32.           
  33.         /** 
  34.          * 请求服务器删除Request-URI所标识的资源 
  35.          */  
  36.         DELETE  (4"DELETE"),   
  37.           
  38.         /** 
  39.          * 请求服务器回送收到的请求信息,主要用于测试或诊断 
  40.          */  
  41.         TRACE(5"TRACE"),   
  42.           
  43.         /** 
  44.          * 向指定资源位置上传其最新内容(部分更新,非幂等) 
  45.          */  
  46.         PATCH   (6"PATCH"),  
  47.           
  48.         /** 
  49.          * 返回服务器针对特定资源所支持的HTTP请求方法。 
  50.          * 也可以利用向Web服务器发送'*'的请求来测试服务器的功能性 
  51.          */  
  52.         OPTIONS (7"OPTIONS"),   
  53.           
  54. //      /**  
  55. //       * HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器  
  56. //       */  
  57. //      CONNECT(99, "CONNECT"),  
  58.         ;  
  59.           
  60.         private int code;  
  61.         private String name;  
  62.           
  63.         private HttpMethods(int code, String name){  
  64.             this.code = code;  
  65.             this.name = name;  
  66.         }  
  67.         public String getName() {  
  68.             return name;  
  69.         }  
  70.         public int getCode() {  
  71.             return code;  
  72.         }  
  73.     }  

通过getRequest方法,来实例化对应方法的请求对象。

[java] view plain copy
 print?
  1. /** 
  2.  * 根据请求方法名,获取request对象 
  3.  *  
  4.  * @param url                   资源地址 
  5.  * @param method            请求方式 
  6.  * @return 
  7.  */  
  8. private static HttpRequestBase getRequest(String url, HttpMethods method) {  
  9.     HttpRequestBase request = null;  
  10.     switch (method.getCode()) {  
  11.         case 0:// HttpGet  
  12.             request = new HttpGet(url);  
  13.             break;  
  14.         case 1:// HttpPost  
  15.             request = new HttpPost(url);  
  16.             break;  
  17.         case 2:// HttpHead  
  18.             request = new HttpHead(url);  
  19.             break;  
  20.         case 3:// HttpPut  
  21.             request = new HttpPut(url);  
  22.             break;  
  23.         case 4:// HttpDelete  
  24.             request = new HttpDelete(url);  
  25.             break;  
  26.         case 5:// HttpTrace  
  27.             request = new HttpTrace(url);  
  28.             break;  
  29.         case 6:// HttpPatch  
  30.             request = new HttpPatch(url);  
  31.             break;  
  32.         case 7:// HttpOptions  
  33.             request = new HttpOptions(url);  
  34.             break;  
  35.         default:  
  36.             request = new HttpPost(url);  
  37.             break;  
  38.     }  
  39.     return request;  
  40. }  

当然最后的关闭链接也是一个小方法:

[java] view plain copy
 print?
  1. /** 
  2.  * 尝试关闭response 
  3.  *  
  4.  * @param resp              HttpResponse对象 
  5.  */  
  6. private static void close(HttpResponse resp) {  
  7.     try {  
  8.         if(resp == nullreturn;  
  9.         //如果CloseableHttpResponse 是resp的父类,则支持关闭  
  10.         if(CloseableHttpResponse.class.isAssignableFrom(resp.getClass())){  
  11.             ((CloseableHttpResponse)resp).close();  
  12.         }  
  13.     } catch (IOException e) {  
  14.         logger.error(e);  
  15.     }  
  16. }  

当然各种参数的组合方法也简单提供一下(为了节约空间,已去掉注释):

[java] view plain copy
 print?
  1. public static String send(String url) throws HttpProcessException {  
  2.     return send(url, Charset.defaultCharset().name());  
  3. }  
  4. public static String send(String url, String encoding) throws HttpProcessException {  
  5.     return send(url, new Header[]{},encoding);  
  6. }  
  7. public static String send(String url, Header[] headers) throws HttpProcessException {  
  8.     return send(url, headers, Charset.defaultCharset().name());  
  9. }  
  10. public static String send(String url, Header[] headers, String encoding) throws HttpProcessException {  
  11.     return send(url, new HashMap<String,String>(), headers, encoding);  
  12. }  
  13. public static String send(String url, Map<String,String>parasMap) throws HttpProcessException {  
  14.     return send(url, parasMap, Charset.defaultCharset().name());  
  15. }  
  16. public static String send(String url, Map<String,String>parasMap, String encoding) throws HttpProcessException {  
  17.     return send(url, parasMap, new Header[]{}, encoding);  
  18. }  
  19. public static String send(String url, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {  
  20.     return send(url, parasMap, headers, Charset.defaultCharset().name());  
  21. }  
  22. public static String send(String url, Map<String,String>parasMap, Header[] headers, String encoding) throws HttpProcessException {  
  23.     return send(url, HttpMethods.POST, parasMap, headers, encoding);  
  24. }     
  25. public static String send(String url, HttpMethods httpMethod) throws HttpProcessException {  
  26.     return send(url, httpMethod, Charset.defaultCharset().name());  
  27. }  
  28. public static String send(String url, HttpMethods httpMethod, String encoding) throws HttpProcessException {  
  29.     return send(url, httpMethod, new Header[]{},encoding);  
  30. }  
  31. public static String send(String url, HttpMethods httpMethod, Header[] headers) throws HttpProcessException {  
  32.     return send(url, httpMethod, headers, Charset.defaultCharset().name());  
  33. }  
  34. public static String send(String url, HttpMethods httpMethod, Header[] headers, String encoding) throws HttpProcessException {  
  35.     return send(url, httpMethod, new HashMap<String, String>(), headers, encoding);  
  36. }  
  37. public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap) throws HttpProcessException {  
  38.     return send(url, httpMethod, parasMap, Charset.defaultCharset().name());  
  39. }  
  40. public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, String encoding) throws HttpProcessException {  
  41.     return send(url, httpMethod, parasMap, new Header[]{}, encoding);  
  42. }  
  43. public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {  
  44.     return send(url, httpMethod, parasMap, headers, Charset.defaultCharset().name());  
  45. }     
  46. public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers, String encoding) throws HttpProcessException {  
  47.     return send(create(url), url, httpMethod, parasMap, headers, encoding);  
  48. }  
  49.   
  50. public static String send(HttpClient client, String url) throws HttpProcessException {  
  51.     return send(client, url, Charset.defaultCharset().name());  
  52. }  
  53. public static String send(HttpClient client, String url, String encoding) throws HttpProcessException {  
  54.     return send(client, url, new Header[]{}, encoding);  
  55. }  
  56. public static String send(HttpClient client, String url, Header[] headers) throws HttpProcessException {  
  57.     return send(client, url, headers, Charset.defaultCharset().name());  
  58. }  
  59. public static String send(HttpClient client, String url, Header[] headers, String encoding) throws HttpProcessException {  
  60.     return send(client, url, new HashMap<String, String>(), headers, encoding);  
  61. }  
  62. public static String send(HttpClient client, String url, Map<String,String>parasMap) throws HttpProcessException {  
  63.     return send(client, url, parasMap, Charset.defaultCharset().name());  
  64. }  
  65. public static String send(HttpClient client, String url, Map<String,String>parasMap, String encoding) throws HttpProcessException {  
  66.     return send(client, url, parasMap, new Header[]{}, encoding);  
  67. }  
  68. public static String send(HttpClient client, String url, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {  
  69.     return send(client, url, parasMap, headers, Charset.defaultCharset().name());  
  70. }  
  71. public static String send(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  72.     return send(client, url, HttpMethods.POST, parasMap, headers, encoding);  
  73. }  
  74. public static String send(HttpClient client, String url, HttpMethods httpMethod) throws HttpProcessException {  
  75.     return send(client, url, httpMethod, Charset.defaultCharset().name());  
  76. }  
  77. public static String send(HttpClient client, String url, HttpMethods httpMethod, String encoding) throws HttpProcessException {  
  78.     return send(client, url, httpMethod, new Header[]{}, encoding);  
  79. }  
  80. public static String send(HttpClient client, String url, HttpMethods httpMethod, Header[] headers) throws HttpProcessException {  
  81.     return send(client, url, httpMethod, headers, Charset.defaultCharset().name());  
  82. }  
  83. public static String send(HttpClient client, String url, HttpMethods httpMethod, Header[] headers, String encoding) throws HttpProcessException {  
  84.     return send(client, url, httpMethod, new HashMap<String, String>(), headers, encoding);  
  85. }  
  86. public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap) throws HttpProcessException {  
  87.     return send(client, url, httpMethod, parasMap, Charset.defaultCharset().name());  
  88. }  
  89. public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap, String encoding) throws HttpProcessException {  
  90.     return send(client, url, httpMethod, parasMap, new Header[]{}, encoding);  
  91. }  
  92. public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {  
  93.     return send(client, url, httpMethod, parasMap, headers, Charset.defaultCharset().name());  
  94. }  

可以看到上面这一堆方法,其实主要分成2类,一类是传入client对象的,一组是没有传入的。也就是说该工具类提供了一种默认的client对象。这个将会在下一篇文章会有补充。


当然,为了方便操作,还是提供了get、post、put、patch、delete、head、options、trace等方法,由于推荐使用send方法,所以这几个方法只是做了一个简单的调用:

[java] view plain copy
 print?
  1. public static String get(String url, Header[] headers,String encoding) throws HttpProcessException {  
  2.     return get(create(url), url, headers, encoding);  
  3. }     
  4. public static String get(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {  
  5.     return send(client, url, HttpMethods.GET, headers, encoding);  
  6. }  
  7.   
  8. public static String post(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  9.     return post(create(url), url, parasMap, headers, encoding);  
  10. }  
  11. public static String post(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  12.     return send(client, url, HttpMethods.POST, parasMap, headers, encoding);  
  13. }  
  14.   
  15. public static String put(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  16.     return put(create(url), url, parasMap, headers, encoding);  
  17. }  
  18. public static String put(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  19.     return send(client, url, HttpMethods.PUT, parasMap, headers, encoding);  
  20. }  
  21.   
  22. public static String delete(String url, Header[] headers,String encoding) throws HttpProcessException {  
  23.     return delete(create(url), url, headers, encoding);  
  24. }  
  25. public static String delete(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {  
  26.     return send(client, url, HttpMethods.DELETE, headers, encoding);  
  27. }  
  28.   
  29. public static String patch(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {  
  30.     return patch(create(url), url, parasMap, headers, encoding);  
  31. }  
  32. public static String patch(HttpClient client, String url, Map<String,String>parasMap, Header[] headers,String encoding) throws HttpProcessException {  
  33.     return send(client, url, HttpMethods.PATCH, parasMap, headers, encoding);  
  34. }  
  35.   
  36. public static String head(String url, Header[] headers,String encoding) throws HttpProcessException {  
  37.     return head(create(url), url, headers, encoding);  
  38. }  
  39. public static String head(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {  
  40.     return send(client, url, HttpMethods.HEAD, headers, encoding);  
  41. }  
  42.   
  43. public static String options(String url, Header[] headers,String encoding) throws HttpProcessException {  
  44.     return options(create(url), url, headers, encoding);  
  45. }  
  46. public static String options(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {  
  47.     return send(client, url, HttpMethods.OPTIONS, headers, encoding);  
  48. }  
  49.   
  50. public static String trace(String url, Header[] headers,String encoding) throws HttpProcessException {  
  51.     return trace(create(url), url, headers, encoding);  
  52. }  
  53. public static String trace(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {  
  54.     return send(client, url, HttpMethods.TRACE, headers, encoding);  
  55. }  

差点忘记了,最后还有一个简单的通用工具类

[java] view plain copy
 print?
  1. /**  
  2.  *  
  3.  * @author arron 
  4.  * @date 2015年11月10日 下午12:49:26  
  5.  * @version 1.0  
  6.  */  
  7. public class Utils {  
  8.   
  9.     /** 
  10.      * 检测url是否含有参数,如果有,则把参数加到参数列表中 
  11.      *  
  12.      * @param url                   资源地址 
  13.      * @param nvps              参数列表 
  14.      * @return  返回去掉参数的url 
  15.      */  
  16.     public static String checkHasParas(String url, List<NameValuePair> nvps) {  
  17.         // 检测url中是否存在参数  
  18.         if (url.contains("?") && url.indexOf("?") < url.indexOf("=")) {  
  19.             Map<String, String> map = buildParas(url.substring(url  
  20.                     .indexOf("?") + 1));  
  21.             map2List(nvps, map);  
  22.             url = url.substring(0, url.indexOf("?"));  
  23.         }  
  24.         return url;  
  25.     }  
  26.   
  27.     /** 
  28.      * 参数转换,将map中的参数,转到参数列表中 
  29.      *  
  30.      * @param nvps              参数列表 
  31.      * @param map               参数列表(map) 
  32.      */  
  33.     public static void map2List(List<NameValuePair> nvps, Map<String, String> map) {  
  34.         if(map==nullreturn;  
  35.         // 拼接参数  
  36.         for (Entry<String, String> entry : map.entrySet()) {  
  37.             nvps.add(new BasicNameValuePair(entry.getKey(), entry  
  38.                     .getValue()));  
  39.         }  
  40.     }  
  41.       
  42.       
  43.     /** 
  44.      * 生成参数 
  45.      * 参数格式“k1=v1&k2=v2” 
  46.      *  
  47.      * @param paras             参数列表 
  48.      * @return                      返回参数列表(map) 
  49.      */  
  50.     public static Map<String,String> buildParas(String paras){  
  51.         String[] p = paras.split("&");  
  52.         String[][] ps = new String[p.length][2];  
  53.         int pos = 0;  
  54.         for (int i = 0; i < p.length; i++) {  
  55.             pos = p[i].indexOf("=");  
  56.             ps[i][0]=p[i].substring(0,pos);  
  57.             ps[i][1]=p[i].substring(pos+1);  
  58.             pos = 0;  
  59.         }  
  60.         return buildParas(ps);  
  61.     }  
  62.       
  63.     /** 
  64.      * 生成参数 
  65.      * 参数类型:{{"k1","v1"},{"k2","v2"}} 
  66.      *  
  67.      * @param paras                 参数列表 
  68.      * @return                      返回参数列表(map) 
  69.      */  
  70.     public static Map<String,String> buildParas(String[][] paras){  
  71.         // 创建参数队列      
  72.         Map<String,String> map = new HashMap<String, String>();  
  73.         for (String[] para: paras) {  
  74.             map.put(para[0], para[1]);  
  75.         }  
  76.         return map;  
  77.     }  
  78.       
  79. }  

简单的封装就是这样了。


由于HttpClient和Header都作为参数传入,所以也可以进行扩展,比如代理、ssl等都是对HttpClient进行配置的,下面的文章就分别分享一下如何插件式配置HttpClient以及Header。敬请期待。

0 0