转:轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)
搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用。调用关系不清楚,结构有点混乱。所以也就萌生了自己封装HttpClient工具类的想法。要做就做最好的,本工具类支持插件式配置Header、插件式配置httpclient对象,这样就可以方便地自定义header信息、配置ssl、配置proxy等。
相关jar包下载:http://search.maven.org/#search%7Cga%7C1%7Chttpasyncclient
是不是觉得说的有点悬乎了,那就先看看调用吧:
- public static void testSimple() throws HttpProcessException{
- String url = "http://www.oschina.net";
- //简单调用
- String resp = HttpClientUtil.send(url);
- System.out.println("请求结果内容长度:"+ resp.length());
- }
- public static void testOne() throws HttpProcessException{
- String url = "https://sso.tgb.com:8443/cas/login";
- //自定义HttpClient,设置超时、代理、ssl
- //HttpClient client= HCB.custom().timeout(10000).proxy("127.0.0.1", 8087).ssl().build();//采用默认方式(绕过证书验证)
- HttpClient client= HCB.custom().timeout(10000).ssl("D:\\keys\\wsriakey","tomcat").build();
- //设置header信息
- Header[] headers=HttpHeader.custom().keepAlive("false").connection("close").contentType(Headers.APP_FORM_URLENCODED).build();
- //执行请求
- String resp=HttpClientUtil.send(client, url, headers);
- System.out.println("请求结果如下:");
- System.out.println(resp);
- }
轻松配置了代理、自定义证书的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方式传入参数是习惯使然,不做过多的解释。
编码这个参数主要是为了为待提交的数据和反馈结果进行转码处理。
简单说一下流程:
- 创建请求对象request;
- 为request设置header信息;
- 判断当前请求对象是否是HttpEntityEnclosingRequestBase的子类,如果是,则支持setEntity方法,来设置参数。
- 执行请求,并拿到结果(同步阻塞);
- 获取并解码请求结果实体;
- 关闭链接
就是这么简单,具体来看看代码吧:
- /**
- * 请求资源或服务,自定义client对象,传入请求参数,设置内容类型,并指定参数和返回数据的编码
- *
- * @param client client对象
- * @param url 资源地址
- * @param httpMethod 请求方法
- * @param parasMap 请求参数
- * @param headers 请求头信息
- * @param encoding 编码
- * @return 返回处理结果
- * @throws HttpProcessException
- */
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap,
- Header[] headers, String encoding) throws HttpProcessException {
- String body = "";
- try {
- //创建请求对象
- HttpRequestBase request = getRequest(url, httpMethod);
- //设置header信息
- request.setHeaders(headers);
- //判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
- if(HttpEntityEnclosingRequestBase.class.isAssignableFrom(request.getClass())){
- List<NameValuePair> nvps = new ArrayList<NameValuePair>();
- //检测url中是否存在参数
- url = Utils.checkHasParas(url, nvps);
- //装填参数
- Utils.map2List(nvps, parasMap);
- //设置参数到请求对象中
- ((HttpEntityEnclosingRequestBase)request).setEntity(new UrlEncodedFormEntity(nvps, encoding));
- logger.debug("请求地址:"+url);
- if(nvps.size()>0){
- logger.debug("请求参数:"+nvps.toString());
- }
- }else{
- int idx = url.indexOf("?");
- logger.debug("请求地址:"+url.substring(0, (idx>0 ? idx-1:url.length()-1)));
- if(idx>0){
- logger.debug("请求参数:"+url.substring(idx+1));
- }
- }
- //调用发送请求
- body = execute(client, request, url, encoding);
- } catch (UnsupportedEncodingException e) {
- throw new HttpProcessException(e);
- }
- return body;
- }
- /**
- * 请求资源或服务
- *
- * @param client client对象
- * @param request 请求对象
- * @param url 资源地址
- * @param parasMap 请求参数
- * @param encoding 编码
- * @return 返回处理结果
- * @throws HttpProcessException
- */
- private static String execute(HttpClient client, HttpRequestBase request,String url, String encoding) throws HttpProcessException {
- String body = "";
- HttpResponse response =null;
- try {
- //执行请求操作,并拿到结果(同步阻塞)
- response = client.execute(request);
- //获取结果实体
- HttpEntity entity = response.getEntity();
- if (entity != null) {
- //按指定编码转换结果实体为String类型
- body = EntityUtils.toString(entity, encoding);
- logger.debug(body);
- }
- EntityUtils.consume(entity);
- } catch (ParseException | IOException e) {
- throw new HttpProcessException(e);
- } finally {
- close(response);
- }
- return body;
- }
第一个方法中,我们看到有HttpMethods类型的参数,在创建request对象时,用到了它。它是什么呢?其实只是一个枚举类:
- /**
- * 枚举HttpMethods方法
- *
- * @author arron
- * @date 2015年11月17日 下午4:45:59
- * @version 1.0
- */
- public enum HttpMethods{
- /**
- * 求获取Request-URI所标识的资源
- */
- GET(0, "GET"),
- /**
- * 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
- * POST请求可能会导致新的资源的建立和/或已有资源的修改
- */
- POST(1, "POST"),
- /**
- * 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。
- * 这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息
- * 只获取响应信息报头
- */
- HEAD(2, "HEAD"),
- /**
- * 向指定资源位置上传其最新内容(全部更新,操作幂等)
- */
- PUT (3, "PUT"),
- /**
- * 请求服务器删除Request-URI所标识的资源
- */
- DELETE (4, "DELETE"),
- /**
- * 请求服务器回送收到的请求信息,主要用于测试或诊断
- */
- TRACE(5, "TRACE"),
- /**
- * 向指定资源位置上传其最新内容(部分更新,非幂等)
- */
- PATCH (6, "PATCH"),
- /**
- * 返回服务器针对特定资源所支持的HTTP请求方法。
- * 也可以利用向Web服务器发送'*'的请求来测试服务器的功能性
- */
- OPTIONS (7, "OPTIONS"),
- // /**
- // * HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
- // */
- // CONNECT(99, "CONNECT"),
- ;
- private int code;
- private String name;
- private HttpMethods(int code, String name){
- this.code = code;
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public int getCode() {
- return code;
- }
- }
通过getRequest方法,来实例化对应方法的请求对象。
- /**
- * 根据请求方法名,获取request对象
- *
- * @param url 资源地址
- * @param method 请求方式
- * @return
- */
- private static HttpRequestBase getRequest(String url, HttpMethods method) {
- HttpRequestBase request = null;
- switch (method.getCode()) {
- case 0:// HttpGet
- request = new HttpGet(url);
- break;
- case 1:// HttpPost
- request = new HttpPost(url);
- break;
- case 2:// HttpHead
- request = new HttpHead(url);
- break;
- case 3:// HttpPut
- request = new HttpPut(url);
- break;
- case 4:// HttpDelete
- request = new HttpDelete(url);
- break;
- case 5:// HttpTrace
- request = new HttpTrace(url);
- break;
- case 6:// HttpPatch
- request = new HttpPatch(url);
- break;
- case 7:// HttpOptions
- request = new HttpOptions(url);
- break;
- default:
- request = new HttpPost(url);
- break;
- }
- return request;
- }
当然最后的关闭链接也是一个小方法:
- /**
- * 尝试关闭response
- *
- * @param resp HttpResponse对象
- */
- private static void close(HttpResponse resp) {
- try {
- if(resp == null) return;
- //如果CloseableHttpResponse 是resp的父类,则支持关闭
- if(CloseableHttpResponse.class.isAssignableFrom(resp.getClass())){
- ((CloseableHttpResponse)resp).close();
- }
- } catch (IOException e) {
- logger.error(e);
- }
- }
当然各种参数的组合方法也简单提供一下(为了节约空间,已去掉注释):
- public static String send(String url) throws HttpProcessException {
- return send(url, Charset.defaultCharset().name());
- }
- public static String send(String url, String encoding) throws HttpProcessException {
- return send(url, new Header[]{},encoding);
- }
- public static String send(String url, Header[] headers) throws HttpProcessException {
- return send(url, headers, Charset.defaultCharset().name());
- }
- public static String send(String url, Header[] headers, String encoding) throws HttpProcessException {
- return send(url, new HashMap<String,String>(), headers, encoding);
- }
- public static String send(String url, Map<String,String>parasMap) throws HttpProcessException {
- return send(url, parasMap, Charset.defaultCharset().name());
- }
- public static String send(String url, Map<String,String>parasMap, String encoding) throws HttpProcessException {
- return send(url, parasMap, new Header[]{}, encoding);
- }
- public static String send(String url, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {
- return send(url, parasMap, headers, Charset.defaultCharset().name());
- }
- public static String send(String url, Map<String,String>parasMap, Header[] headers, String encoding) throws HttpProcessException {
- return send(url, HttpMethods.POST, parasMap, headers, encoding);
- }
- public static String send(String url, HttpMethods httpMethod) throws HttpProcessException {
- return send(url, httpMethod, Charset.defaultCharset().name());
- }
- public static String send(String url, HttpMethods httpMethod, String encoding) throws HttpProcessException {
- return send(url, httpMethod, new Header[]{},encoding);
- }
- public static String send(String url, HttpMethods httpMethod, Header[] headers) throws HttpProcessException {
- return send(url, httpMethod, headers, Charset.defaultCharset().name());
- }
- public static String send(String url, HttpMethods httpMethod, Header[] headers, String encoding) throws HttpProcessException {
- return send(url, httpMethod, new HashMap<String, String>(), headers, encoding);
- }
- public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap) throws HttpProcessException {
- return send(url, httpMethod, parasMap, Charset.defaultCharset().name());
- }
- public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, String encoding) throws HttpProcessException {
- return send(url, httpMethod, parasMap, new Header[]{}, encoding);
- }
- public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {
- return send(url, httpMethod, parasMap, headers, Charset.defaultCharset().name());
- }
- public static String send(String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers, String encoding) throws HttpProcessException {
- return send(create(url), url, httpMethod, parasMap, headers, encoding);
- }
- public static String send(HttpClient client, String url) throws HttpProcessException {
- return send(client, url, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, String encoding) throws HttpProcessException {
- return send(client, url, new Header[]{}, encoding);
- }
- public static String send(HttpClient client, String url, Header[] headers) throws HttpProcessException {
- return send(client, url, headers, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, Header[] headers, String encoding) throws HttpProcessException {
- return send(client, url, new HashMap<String, String>(), headers, encoding);
- }
- public static String send(HttpClient client, String url, Map<String,String>parasMap) throws HttpProcessException {
- return send(client, url, parasMap, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, Map<String,String>parasMap, String encoding) throws HttpProcessException {
- return send(client, url, parasMap, new Header[]{}, encoding);
- }
- public static String send(HttpClient client, String url, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {
- return send(client, url, parasMap, headers, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.POST, parasMap, headers, encoding);
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod) throws HttpProcessException {
- return send(client, url, httpMethod, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, String encoding) throws HttpProcessException {
- return send(client, url, httpMethod, new Header[]{}, encoding);
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Header[] headers) throws HttpProcessException {
- return send(client, url, httpMethod, headers, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Header[] headers, String encoding) throws HttpProcessException {
- return send(client, url, httpMethod, new HashMap<String, String>(), headers, encoding);
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap) throws HttpProcessException {
- return send(client, url, httpMethod, parasMap, Charset.defaultCharset().name());
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap, String encoding) throws HttpProcessException {
- return send(client, url, httpMethod, parasMap, new Header[]{}, encoding);
- }
- public static String send(HttpClient client, String url, HttpMethods httpMethod, Map<String,String>parasMap, Header[] headers) throws HttpProcessException {
- return send(client, url, httpMethod, parasMap, headers, Charset.defaultCharset().name());
- }
可以看到上面这一堆方法,其实主要分成2类,一类是传入client对象的,一组是没有传入的。也就是说该工具类提供了一种默认的client对象。这个将会在下一篇文章会有补充。
当然,为了方便操作,还是提供了get、post、put、patch、delete、head、options、trace等方法,由于推荐使用send方法,所以这几个方法只是做了一个简单的调用:
- public static String get(String url, Header[] headers,String encoding) throws HttpProcessException {
- return get(create(url), url, headers, encoding);
- }
- public static String get(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.GET, headers, encoding);
- }
- public static String post(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return post(create(url), url, parasMap, headers, encoding);
- }
- public static String post(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.POST, parasMap, headers, encoding);
- }
- public static String put(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return put(create(url), url, parasMap, headers, encoding);
- }
- public static String put(HttpClient client, String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.PUT, parasMap, headers, encoding);
- }
- public static String delete(String url, Header[] headers,String encoding) throws HttpProcessException {
- return delete(create(url), url, headers, encoding);
- }
- public static String delete(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.DELETE, headers, encoding);
- }
- public static String patch(String url, Map<String,String>parasMap,Header[] headers,String encoding) throws HttpProcessException {
- return patch(create(url), url, parasMap, headers, encoding);
- }
- public static String patch(HttpClient client, String url, Map<String,String>parasMap, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.PATCH, parasMap, headers, encoding);
- }
- public static String head(String url, Header[] headers,String encoding) throws HttpProcessException {
- return head(create(url), url, headers, encoding);
- }
- public static String head(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.HEAD, headers, encoding);
- }
- public static String options(String url, Header[] headers,String encoding) throws HttpProcessException {
- return options(create(url), url, headers, encoding);
- }
- public static String options(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.OPTIONS, headers, encoding);
- }
- public static String trace(String url, Header[] headers,String encoding) throws HttpProcessException {
- return trace(create(url), url, headers, encoding);
- }
- public static String trace(HttpClient client, String url, Header[] headers,String encoding) throws HttpProcessException {
- return send(client, url, HttpMethods.TRACE, headers, encoding);
- }
差点忘记了,最后还有一个简单的通用工具类
- /**
- *
- * @author arron
- * @date 2015年11月10日 下午12:49:26
- * @version 1.0
- */
- public class Utils {
- /**
- * 检测url是否含有参数,如果有,则把参数加到参数列表中
- *
- * @param url 资源地址
- * @param nvps 参数列表
- * @return 返回去掉参数的url
- */
- public static String checkHasParas(String url, List<NameValuePair> nvps) {
- // 检测url中是否存在参数
- if (url.contains("?") && url.indexOf("?") < url.indexOf("=")) {
- Map<String, String> map = buildParas(url.substring(url
- .indexOf("?") + 1));
- map2List(nvps, map);
- url = url.substring(0, url.indexOf("?"));
- }
- return url;
- }
- /**
- * 参数转换,将map中的参数,转到参数列表中
- *
- * @param nvps 参数列表
- * @param map 参数列表(map)
- */
- public static void map2List(List<NameValuePair> nvps, Map<String, String> map) {
- if(map==null) return;
- // 拼接参数
- for (Entry<String, String> entry : map.entrySet()) {
- nvps.add(new BasicNameValuePair(entry.getKey(), entry
- .getValue()));
- }
- }
- /**
- * 生成参数
- * 参数格式“k1=v1&k2=v2”
- *
- * @param paras 参数列表
- * @return 返回参数列表(map)
- */
- public static Map<String,String> buildParas(String paras){
- String[] p = paras.split("&");
- String[][] ps = new String[p.length][2];
- int pos = 0;
- for (int i = 0; i < p.length; i++) {
- pos = p[i].indexOf("=");
- ps[i][0]=p[i].substring(0,pos);
- ps[i][1]=p[i].substring(pos+1);
- pos = 0;
- }
- return buildParas(ps);
- }
- /**
- * 生成参数
- * 参数类型:{{"k1","v1"},{"k2","v2"}}
- *
- * @param paras 参数列表
- * @return 返回参数列表(map)
- */
- public static Map<String,String> buildParas(String[][] paras){
- // 创建参数队列
- Map<String,String> map = new HashMap<String, String>();
- for (String[] para: paras) {
- map.put(para[0], para[1]);
- }
- return map;
- }
- }
简单的封装就是这样了。
转:轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)的更多相关文章
- 轻松把玩HttpClient之封装HttpClient工具类(五),携带Cookie的请求
近期更新了一下HttpClientUtil工具类代码,主要是加入了一个參数HttpContext,这个是用来干嘛的呢?事实上是用来保存和传递Cookie所须要的. 由于我们有非常多时候都须要登录.然后 ...
- HttpClient 常用方法封装
简介 在平时写代码中,经常需要对接口进行访问,对于 http 协议 rest 风格的接口请求,大多使用 HttpClient 工具进行编写,想着方便就寻思着把一些常用的方法进行封装,便于平时快速的使用 ...
- 完成OSS.Http底层HttpClient重构封装 支持标准库
OSS.Http项目对于.Net Standard标准库的支持已经迁移完毕,OSS开源系列两个最底层的类库已经具备跨运行时支持的能力.由于OSS.Http类库是几年前我参照RestSharp的思路,完 ...
- 封装HttpClient进行http请求与https请求
一.https忽略证书 /** * 用于进行Https请求的HttpClient * * @author joey * */ public class SSLClient { public stati ...
- Qt 访问网络的 HttpClient(封装QNetworkAccessManager,且有服务端)
Qt 使用 QNetworkAccessManager 访问网络,这里对其进行了简单的封装,访问网络的代码可以简化为: 1 2 3 HttpClient("http://localhost: ...
- httpclient常规封装的方法
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compr ...
- httpClient简单封装
package com.Interface.util; import java.util.Iterator; import java.util.Map; import org.apache.commo ...
- swfdump——从内存中提取swf的工具
刚刚整理代码时发现以前写的从进程的内存镜像中提取swf文件的工具,现在分享出来,希望能帮到有需要的朋友.这个小工具是命令行使用,没有界面,可以很方便的从指定进程中(比如浏览器,swf播放器等等),按s ...
- C#中那些常用的工具类(Utility Class)(一)
代码越写越多,但是我们也需要经常去反思那些写过的代码,Utility Class就是这一类需要特别去反思总结的类,这些类像工具一样,我们经常通过一些静态方法,通过传入一些参数,然后得到我们需要的结果, ...
随机推荐
- js简单函数(动态交互)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- 6.1Hadoop属性Configuration配置API
6.1 Hadoop属性配置API Hadoop需要添加一些自定义的属性值,可以通过Configuration类的实例来加载xml配置文件中的属性值. (1) xml配置文件的格式 <?x ...
- lrd 模拟 总结
觉得是时候总结一下达哥的考试了!达哥的考试我就没有考好过,就之前达哥的考试都是人家ak我爆零,然后这次也不例外,我总是想在考场上尝试一些新的东西,其实就是作死行为,有的时候这种行为可以为我带来收益但是 ...
- Scrapy进阶知识点总结(二)——选择器Selectors
1. Selectors选择器 在抓取网页时,您需要执行的最常见任务是从HTML源提取数据.有几个库可用于实现此目的,例如: BeautifulSoup是Python程序员中非常流行的Web抓取库,它 ...
- 关于设备与canvas画不出来的解决办法
连续四天解决一个在三星手机上面画canvas的倒计时饼图不出来的问题,困惑了很久,用了很多办法,甚至重写了那个方法,还是没有解决,大神给的思路是给父级加 "overflow: visible ...
- office 2019 激活
office 2019 激活: 1.新建文本文档 激活.txt 2.复制以下内容到 激活.txt 中 @echo off (cd /d >& title Office Acti ...
- VS Code 之 Jupyter NoteBook 初试
一.前言 在今年九月的 PyCon China 大会上,官宣了一项 VS Code Python 的全新功能:Visual Studio Code Python 插件将提供 Jupyter Noteb ...
- golang学习--go中'继承'和多态
golang中没有继承的概念,这个struct属性上的继承,但是可以用匿名字段来模拟这个过程,方法上面的继承要使用接口.多态可以通过接口实现.可以看一下代码. package main import ...
- Linux配置SSH和Xshell连接服务器
>>>>>Ubuntu安装和配置ssh教程 SSH分为客户端 openssh-client 和服务器 openssh-server,可以利用以下命令确认电脑 上是否安装了 ...
- 【2018寒假集训 Day2】【动态规划】挖地雷
挖地雷(Mine) 在一个地图上有N 个地窖(N<=200),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径,并规定路径都是单向的,且从编号小的地窖通向编号大的地窖.某人可以从任一处 ...