HttpClient详细使用示例

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

    HTTP和浏览器有点像,但却不是浏览器。很多人觉得既然HttpClient是一个HTTP客户端编程工具,很多人把他当做浏览器来理解,但是其实HttpClient不是浏览器,它是一个HTTP通信库,因此它只提供一个通用浏览器应用程序所期望的功能子集,最根本的区别是HttpClient中没有用户界面,浏览器需要一个渲染引擎来显示页面,并解释用户输入,例如鼠标点击显示页面上的某处,有一个布局引擎,计算如何显示HTML页面,包括级联样式表和图像。javascript解释器运行嵌入HTML页面或从HTML页面引用的javascript代码。来自用户界面的事件被传递到javascript解释器进行处理。除此之外,还有用于插件的接口,可以处理Applet,嵌入式媒体对象(如pdf文件,Quicktime电影和Flash动画)或ActiveX控件(可以执行任何操作)。HttpClient只能以编程的方式通过其API用于传输和接受HTTP消息。

HttpClient的主要功能:

实现了所有 HTTP 的方法(GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等)
支持 HTTPS 协议
支持代理服务器(Nginx等)等
支持自动(跳转)转向

环境说明:JDK1.8、SpringBoot
在这里插入图片描述
注:本人引入此依赖的目的是,在后续示例中,会用到“将对象转化为json字符串的功能”,也可以引其他有此功能的依赖。

注:SpringBoot的基本依赖配置,这里就不再多说了。

详细使用示例
声明:此示例中,以JAVA发送HttpClient(在test里面单元测试发送的);也是以JAVA接收的(在controller里面接收的)。

声明:下面的代码,本人亲测有效。

GET无参:
HttpClient发送示例:

 /**
	 * GET---无参测试
	 *
	 * @date 2018年7月13日 下午4:18:50
	 */
	@Test
	public void doGetTestOne() {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		// 创建Get请求
		HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerOne");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

在这里插入图片描述
GET有参(方式一:直接拼接URL):
HttpClient发送示例:

 /**
	 * GET---有参测试 (方式一:手动在url后面加上参数)
	 *
	 * @date 2018年7月13日 下午4:19:23
	 */
	@Test
	public void doGetTestWayOne() {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		StringBuffer params = new StringBuffer();
		try {
			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
			params.append("name=" + URLEncoder.encode("&", "utf-8"));
			params.append("&");
			params.append("age=24");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
 
		// 创建Get请求
		HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerTwo" + "?" + params);
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 配置信息
			RequestConfig requestConfig = RequestConfig.custom()
					// 设置连接超时时间(单位毫秒)
					.setConnectTimeout(5000)
					// 设置请求超时时间(单位毫秒)
					.setConnectionRequestTimeout(5000)
					// socket读写超时时间(单位毫秒)
					.setSocketTimeout(5000)
					// 设置是否允许重定向(默认为true)
					.setRedirectsEnabled(true).build();
 
			// 将上面的配置信息 运用到这个Get请求里
			httpGet.setConfig(requestConfig);
 
			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);
 
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

对应接收示例:
在这里插入图片描述
GET有参(方式二:使用URI获得HttpGet):
HttpClient发送示例:

 /**
	 * GET---有参测试 (方式二:将参数放入键值对类中,再放入URI中,从而通过URI得到HttpGet实例)
	 *
	 * @date 2018年7月13日 下午4:19:23
	 */
	@Test
	public void doGetTestWayTwo() {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		URI uri = null;
		try {
			// 将参数放入键值对类NameValuePair中,再放入集合中
			List<NameValuePair> params = new ArrayList<>();
			params.add(new BasicNameValuePair("name", "&"));
			params.add(new BasicNameValuePair("age", "18"));
			// 设置uri信息,并将参数集合放入uri;
			// 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
			uri = new URIBuilder().setScheme("http").setHost("localhost")
					              .setPort(12345).setPath("/doGetControllerTwo")
					              .setParameters(params).build();
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
		// 创建Get请求
		HttpGet httpGet = new HttpGet(uri);
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 配置信息
			RequestConfig requestConfig = RequestConfig.custom()
					// 设置连接超时时间(单位毫秒)
					.setConnectTimeout(5000)
					// 设置请求超时时间(单位毫秒)
					.setConnectionRequestTimeout(5000)
					// socket读写超时时间(单位毫秒)
					.setSocketTimeout(5000)
					// 设置是否允许重定向(默认为true)
					.setRedirectsEnabled(true).build();
 
			// 将上面的配置信息 运用到这个Get请求里
			httpGet.setConfig(requestConfig);
 
			// 由客户端执行(发送)Get请求
			response = httpClient.execute(httpGet);
 
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

对应接收示例:
在这里插入图片描述

POST无参:
HttpClient发送示例:
/**
* POST—无参测试
*
* @date 2018年7月13日 下午4:18:50
*/
@Test
public void doPostTestOne() {

	// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
	CloseableHttpClient httpClient = HttpClientBuilder.create().build();

	// 创建Post请求
	HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerOne");
	// 响应模型
	CloseableHttpResponse response = null;
	try {
		// 由客户端执行(发送)Post请求
		response = httpClient.execute(httpPost);
		// 从响应模型中获取响应实体
		HttpEntity responseEntity = response.getEntity();

		System.out.println("响应状态为:" + response.getStatusLine());
		if (responseEntity != null) {
			System.out.println("响应内容长度为:" + responseEntity.getContentLength());
			System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
		}
	} catch (ClientProtocolException e) {
		e.printStackTrace();
	} catch (ParseException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		try {
			// 释放资源
			if (httpClient != null) {
				httpClient.close();
			}
			if (response != null) {
				response.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
对应接收示例:

在这里插入图片描述
POST有参(普通参数):
注:POST传递普通参数时,方式与GET一样即可,这里以直接在url后缀上参数的方式示例。

HttpClient发送示例:

 /**
	 * POST---有参测试(普通参数)
	 *
	 * @date 2018年7月13日 下午4:18:50
	 */
	@Test
	public void doPostTestFour() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 参数
		StringBuffer params = new StringBuffer();
		try {
			// 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
			params.append("name=" + URLEncoder.encode("&", "utf-8"));
			params.append("&");
			params.append("age=24");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
 
		// 创建Post请求
		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerFour" + "?" + params);
 
		// 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

对应接收示例:
在这里插入图片描述
POST有参(对象参数):
先给出User类

在这里插入图片描述
HttpClient发送示例:

/**
	 * POST---有参测试(对象参数)
	 *
	 * @date 2018年7月13日 下午4:18:50
	 */
	@Test
	public void doPostTestTwo() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 创建Post请求
		HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerTwo");
		User user = new User();
		user.setName("潘晓婷");
		user.setAge(18);
		user.setGender("女");
		user.setMotto("姿势要优雅~");
		// 我这里利用阿里的fastjson,将Object转换为json字符串;
		// (需要导入com.alibaba.fastjson.JSON包)
		String jsonString = JSON.toJSONString(user);
 
		StringEntity entity = new StringEntity(jsonString, "UTF-8");
 
		// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
		httpPost.setEntity(entity);
 
		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
对应接收示例:

在这里插入图片描述
POST有参(普通参数 + 对象参数):
注:POST传递普通参数时,方式与GET一样即可,这里以通过URI获得HttpPost的方式为例。

先给出User类:

在这里插入图片描述
HttpClient发送示例:

/**
	 * POST---有参测试(普通参数 + 对象参数)
	 *
	 * @date 2018年7月13日 下午4:18:50
	 */
	@Test
	public void doPostTestThree() {
 
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 
		// 创建Post请求
		// 参数
		URI uri = null;
		try {
			// 将参数放入键值对类NameValuePair中,再放入集合中
			List<NameValuePair> params = new ArrayList<>();
			params.add(new BasicNameValuePair("flag", "4"));
			params.add(new BasicNameValuePair("meaning", "这是什么鬼?"));
			// 设置uri信息,并将参数集合放入uri;
			// 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
			uri = new URIBuilder().setScheme("http").setHost("localhost").setPort(12345)
					.setPath("/doPostControllerThree").setParameters(params).build();
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
 
		HttpPost httpPost = new HttpPost(uri);
		// HttpPost httpPost = new
		// HttpPost("http://localhost:12345/doPostControllerThree1");
 
		// 创建user参数
		User user = new User();
		user.setName("潘晓婷");
		user.setAge(18);
		user.setGender("女");
		user.setMotto("姿势要优雅~");
 
		// 将user对象转换为json字符串,并放入entity中
		StringEntity entity = new StringEntity(JSON.toJSONString(user), "UTF-8");
 
		// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
		httpPost.setEntity(entity);
 
		httpPost.setHeader("Content-Type", "application/json;charset=utf8");
 
		// 响应模型
		CloseableHttpResponse response = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			HttpEntity responseEntity = response.getEntity();
 
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				System.out.println("响应内容长度为:" + responseEntity.getContentLength());
				System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 释放资源
				if (httpClient != null) {
					httpClient.close();
				}
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

对应接收示例:
在这里插入图片描述
提示:如果想要知道完整的具体的代码及测试细节,可去下面给的项目代码托管链接,将项目clone下来
进行观察。如果需要运行测试,可以先启动该SpringBoot项目,然后再运行相关test方法,进行
测试。

解决响应乱码问题(示例):
在这里插入图片描述
进行HTTPS请求并进行(或不进行)证书校验(示例):
使用示例:
在这里插入图片描述
相关方法详情(非完美封装):

/**
 * 根据是否是https请求,获取HttpClient客户端
 *
 * TODO 本人这里没有进行完美封装。对于 校不校验校验证书的选择,本人这里是写死
 *      在代码里面的,你们在使用时,可以灵活二次封装。
 *
 * 提示: 此工具类的封装、相关客户端、服务端证书的生成,可参考我的这篇博客:
 *      <linked>https://blog.csdn.net/justry_deng/article/details/91569132</linked>
 *
 *
 * @param isHttps 是否是HTTPS请求
 *
 * @return  HttpClient实例
 * @date 2019/9/18 17:57
 */
private CloseableHttpClient getHttpClient(boolean isHttps) {
   CloseableHttpClient httpClient;
   if (isHttps) {
      SSLConnectionSocketFactory sslSocketFactory;
      try {
         /// 如果不作证书校验的话
         sslSocketFactory = getSocketFactory(false, null, null);
 
         /// 如果需要证书检验的话
         // 证书
         //InputStream ca = this.getClass().getClassLoader().getResourceAsStream("client/ds.crt");
         // 证书的别名,即:key。 注:cAalias只需要保证唯一即可,不过推荐使用生成keystore时使用的别名。
         // String cAalias = System.currentTimeMillis() + "" + new SecureRandom().nextInt(1000);
         //sslSocketFactory = getSocketFactory(true, ca, cAalias);
      } catch (Exception e) {
         throw new RuntimeException(e);
      }
      httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build();
      return httpClient;
   }
   httpClient = HttpClientBuilder.create().build();
   return httpClient;
}
 
/**
 * HTTPS辅助方法, 为HTTPS请求 创建SSLSocketFactory实例、TrustManager实例
 *
 * @param needVerifyCa
 *         是否需要检验CA证书(即:是否需要检验服务器的身份)
 * @param caInputStream
 *         CA证书。(若不需要检验证书,那么此处传null即可)
 * @param cAalias
 *         别名。(若不需要检验证书,那么此处传null即可)
 *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
 *
 * @return SSLConnectionSocketFactory实例
 * @throws NoSuchAlgorithmException
 *         异常信息
 * @throws CertificateException
 *         异常信息
 * @throws KeyStoreException
 *         异常信息
 * @throws IOException
 *         异常信息
 * @throws KeyManagementException
 *         异常信息
 * @date 2019/6/11 19:52
 */
private static SSLConnectionSocketFactory getSocketFactory(boolean needVerifyCa, InputStream caInputStream, String cAalias)
      throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
      IOException, KeyManagementException {
   X509TrustManager x509TrustManager;
   // https请求,需要校验证书
   if (needVerifyCa) {
      KeyStore keyStore = getKeyStore(caInputStream, cAalias);
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      trustManagerFactory.init(keyStore);
      TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
      if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
         throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
      }
      x509TrustManager = (X509TrustManager) trustManagers[0];
      // 这里传TLS或SSL其实都可以的
      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
      return new SSLConnectionSocketFactory(sslContext);
   }
   // https请求,不作证书校验
   x509TrustManager = new X509TrustManager() {
      @Override
      public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
      }
 
      @Override
      public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
         // 不验证
      }
 
      @Override
      public X509Certificate[] getAcceptedIssuers() {
         return new X509Certificate[0];
      }
   };
   SSLContext sslContext = SSLContext.getInstance("TLS");
   sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
   return new SSLConnectionSocketFactory(sslContext);
}
 
/**
 * 获取(密钥及证书)仓库
 * 注:该仓库用于存放 密钥以及证书
 *
 * @param caInputStream
 *         CA证书(此证书应由要访问的服务端提供)
 * @param cAalias
 *         别名
 *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
 * @return 密钥、证书 仓库
 * @throws KeyStoreException 异常信息
 * @throws CertificateException 异常信息
 * @throws IOException 异常信息
 * @throws NoSuchAlgorithmException 异常信息
 * @date 2019/6/11 18:48
 */
private static KeyStore getKeyStore(InputStream caInputStream, String cAalias)
      throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
   // 证书工厂
   CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
   // 秘钥仓库
   KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
   keyStore.load(null);
   keyStore.setCertificateEntry(cAalias, certificateFactory.generateCertificate(caInputStream));
   return keyStore;
}

application/x-www-form-urlencoded表单请求(示例):
在这里插入图片描述
发送文件(示例):
准备工作:

   如果想要灵活方便的传输文件的话,除了引入org.apache.httpcomponents基本的httpclient依赖外再额外引入org.apache.httpcomponents的httpmime依赖。

P.S.:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。

在pom.xml中额外引入:

org.apache.httpcomponents httpmime 4.5.5

发送端是这样的:
/**
*

  • 发送文件
  • multipart/form-data传递文件(及相关信息)
  • 注:如果想要灵活方便的传输文件的话,
  • 除了引入org.apache.httpcomponents基本的httpclient依赖外
  • 再额外引入org.apache.httpcomponents的httpmime依赖。
  • 追注:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。

*/
@Test
public void test4() {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(“http://localhost:12345/file”);
CloseableHttpResponse response = null;
try {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
// 第一个文件
String filesKey = “files”;
File file1 = new File(“C:\Users\JustryDeng\Desktop\back.jpg”);
multipartEntityBuilder.addBinaryBody(filesKey, file1);
// 第二个文件(多个文件的话,使用同一个key就行,后端用数组或集合进行接收即可)
File file2 = new File(“C:\Users\JustryDeng\Desktop\头像.jpg”);
// 防止服务端收到的文件名乱码。 我们这里可以先将文件名URLEncode,然后服务端拿到文件名时在URLDecode。就能避免乱码问题。
// 文件名其实是放在请求头的Content-Disposition里面进行传输的,如其值为form-data; name=“files”; filename=“头像.jpg”
multipartEntityBuilder.addBinaryBody(filesKey, file2, ContentType.DEFAULT_BINARY, URLEncoder.encode(file2.getName(), “utf-8”));
// 其它参数(注:自定义contentType,设置UTF-8是为了防止服务端拿到的参数出现乱码)
ContentType contentType = ContentType.create(“text/plain”, Charset.forName(“UTF-8”));
multipartEntityBuilder.addTextBody(“name”, “邓沙利文”, contentType);
multipartEntityBuilder.addTextBody(“age”, “25”, contentType);

  HttpEntity httpEntity = multipartEntityBuilder.build();
  httpPost.setEntity(httpEntity);

  response = httpClient.execute(httpPost);
  HttpEntity responseEntity = response.getEntity();
  System.out.println("HTTPS响应状态为:" + response.getStatusLine());
  if (responseEntity != null) {
     System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
     // 主动设置编码,来防止响应乱码
     String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
     System.out.println("HTTPS响应内容为:" + responseStr);
  }

} catch (ParseException | IOException e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

接收端是这样的:
在这里插入图片描述
发送流(示例):
发送端是这样的:

/**
 *
 * 发送流
 *
 */
@Test
public void test5() {
   CloseableHttpClient httpClient = HttpClientBuilder.create().build();
   HttpPost httpPost = new HttpPost("http://localhost:12345/is?name=邓沙利文");
   CloseableHttpResponse response = null;
   try {
      InputStream is = new ByteArrayInputStream("流啊流~".getBytes());
      InputStreamEntity ise = new InputStreamEntity(is);
      httpPost.setEntity(ise);
 
      response = httpClient.execute(httpPost);
      HttpEntity responseEntity = response.getEntity();
      System.out.println("HTTPS响应状态为:" + response.getStatusLine());
      if (responseEntity != null) {
         System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
         // 主动设置编码,来防止响应乱码
         String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
         System.out.println("HTTPS响应内容为:" + responseStr);
      }
   } catch (ParseException | IOException e) {
      e.printStackTrace();
   } finally {
      try {
         // 释放资源
         if (httpClient != null) {
            httpClient.close();
         }
         if (response != null) {
            response.close();
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

接收端是这样的:
在这里插入图片描述

Maven坐标:
<!-- https://mvnrepository.com/artifact/com.arronlong/httpclientutil -->
<dependency>
    <groupId>com.arronlong</groupId>
    <artifactId>httpclientutil</artifactId>
    <version>1.0.4</version>
</dependency>

demo

public static void main(String[] args) throws HttpProcessException, FileNotFoundException {
	String url = "https://github.com/Arronlong/httpclientutil";
	
	//最简单的使用:
	String html = HttpClientUtil.get(HttpConfig.custom().url(url));
	System.out.println(html);
	
	//---------------------------------
	//			【详细说明】
	//--------------------------------
	
	//插件式配置Header(各种header信息、自定义header)
	Header[] headers = HttpHeader.custom()
						 		 .userAgent("javacl")
								 .other("customer", "自定义")
								 .build();
	
	//插件式配置生成HttpClient时所需参数(超时、连接池、ssl、重试)
	HCB hcb = HCB.custom()
				 .timeout(1000) //超时
				 .pool(100, 10) //启用连接池,每个路由最大创建10个链接,总连接数限制为100个
				 .sslpv(SSLProtocolVersion.TLSv1_2) 	//设置ssl版本号,默认SSLv3,也可以调用sslpv("TLSv1.2")
				 .ssl()  	  	//https,支持自定义ssl证书路径和密码,ssl(String keyStorePath, String keyStorepass)
				 .retry(5)		//重试5次
				 ;
	
	HttpClient client = hcb.build();
	
	Map<String, Object> map = new HashMap<String, Object>();
	map.put("key1", "value1");
	map.put("key2", "value2");
	
	//插件式配置请求参数(网址、请求参数、编码、client)
	HttpConfig config = HttpConfig.custom()
	                              .headers(headers)	//设置headers,不需要时则无需设置
	                              .url(url)	          //设置请求的url
	                              .map(map)	          //设置请求参数,没有则无需设置
	                              .encoding("utf-8") //设置请求和返回编码,默认就是Charset.defaultCharset()
	                              .client(client)    //如果只是简单使用,无需设置,会自动获取默认的一个client对象
	                              //.inenc("utf-8")  //设置请求编码,如果请求返回一直,不需要再单独设置
	                              //.inenc("utf-8")	//设置返回编码,如果请求返回一直,不需要再单独设置
	                              //.json("json字符串")                          //json方式请求的话,就不用设置map方法,当然二者可以共用。
	                              //.context(HttpCookies.custom().getContext()) //设置cookie,用于完成携带cookie的操作
	                              //.out(new FileOutputStream("保存地址"))       //下载的话,设置这个方法,否则不要设置
	                              //.files(new String[]{"d:/1.txt","d:/2.txt"}) //上传的话,传递文件路径,一般还需map配置,设置服务器保存路径
	                              ;
	
	
	//使用方式:
	String result1 = HttpClientUtil.get(config);     //get请求
	String result2 = HttpClientUtil.post(config);    //post请求
	System.out.println(result1);
	System.out.println(result2);
	
	//HttpClientUtil.down(config);                   //下载,需要调用config.out(fileOutputStream对象)
	//HttpClientUtil.upload(config);                 //上传,需要调用config.files(文件路径数组)
	
	//如果指向看是否访问正常
	//String result3 = HttpClientUtil.head(config); // 返回Http协议号+状态码
	//int statusCode = HttpClientUtil.status(config);//返回状态码
	
	//[新增方法]sendAndGetResp,可以返回原生的HttpResponse对象,
	//同时返回常用的几类对象:result、header、StatusLine、StatusCode
	HttpResult respResult = HttpClientUtil.sendAndGetResp(config);
	System.out.println("返回结果:\n"+respResult.getResult());
	System.out.println("返回resp-header:"+respResult.getRespHeaders());//可以遍历
	System.out.println("返回具体resp-header:"+respResult.getHeaders("Date"));
	System.out.println("返回StatusLine对象:"+respResult.getStatusLine());
	System.out.println("返回StatusCode:"+respResult.getStatusCode());
	System.out.println("返回HttpResponse对象)(可自行处理):"+respResult.getResp());
	}


log4j.properties

log4j.rootLogger=INFO,stdout,logfile

### \u628a\u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa\u5230\u63a7\u5236\u53f0 ### 

log4j.appender.INFO=org.apache.log4j.ConsoleAppender
log4j.appender.INFO.layout=org.apache.log4j.PatternLayout
log4j.appender.INFO.layout.ConversionPattern=[%-5p] %L method:%l - %m%n

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
#log4j.appender.stdout.layout.ConversionPattern=[%-5p] %L method:%l - %m%n

### \u628a\u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa\u5230\u6587\u4ef6 jbit.log ### 

#log4j.appender.logfile=org.apache.log4j.FileAppender 
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender

log4j.appender.logfile.File=/logs/httpclient/httputil.log

log4j.appender.logfile.DatePattern='.'yyyy-MM-dd

log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 

#log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n 
log4j.appender.logfile.layout.ConversionPattern=[%-5p] %L-%d{yyyy-MM-dd HH:mm:ss,SSS} method:%l - %m%n



HttpClientUtil.
  
package com.arronlong.httpclientutil;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import com.arronlong.httpclientutil.builder.HCB;
import com.arronlong.httpclientutil.common.HttpConfig;
import com.arronlong.httpclientutil.common.HttpMethods;
import com.arronlong.httpclientutil.common.HttpResult;
import com.arronlong.httpclientutil.common.Utils;
import com.arronlong.httpclientutil.exception.HttpProcessException;

/**
 * 使用HttpClient模拟发送(http/https)请求
 * 
 * @author arron
 * @version 1.0
 */
public class HttpClientUtil{
	
	//默认采用的http协议的HttpClient对象
	private static  HttpClient client4HTTP;
	
	//默认采用的https协议的HttpClient对象
	private static HttpClient client4HTTPS;
	
	static{
		try {
			client4HTTP = HCB.custom().build();
			client4HTTPS = HCB.custom().ssl().build();
		} catch (HttpProcessException e) {
			Utils.errorException("创建https协议的HttpClient对象出错:{}", e);
		}
	}
	
	/**
	 * 判定是否开启连接池、及url是http还是https <br>
	 * 		如果已开启连接池,则自动调用build方法,从连接池中获取client对象<br>
	 * 		否则,直接返回相应的默认client对象<br>
	 * 
	 * @param config		请求参数配置
	 * @throws HttpProcessException	http处理异常
	 */
	private static void create(HttpConfig config) throws HttpProcessException  {
		if(config.client()==null){//如果为空,设为默认client对象
			if(config.url().toLowerCase().startsWith("https://")){
				config.client(client4HTTPS);
			}else{
				config.client(client4HTTP);
			}
		}
	}
	
	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	
	/**
	 * 以Get方式,请求资源或服务
	 * 
	 * @param client				client对象
	 * @param url					资源地址
	 * @param headers			请求头信息
	 * @param context			http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return						返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String get(HttpClient client, String url, Header[] headers, HttpContext context, String encoding) throws HttpProcessException {
		return get(HttpConfig.custom().client(client).url(url).headers(headers).context(context).encoding(encoding));
	}
	/**
	 * 以Get方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return	返回结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String get(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.GET));
	}
	
	/**
	 * 以Post方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param parasMap		请求参数
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String post(HttpClient client, String url, Header[] headers, Map<String,Object>parasMap, HttpContext context, String encoding) throws HttpProcessException {
		return post(HttpConfig.custom().client(client).url(url).headers(headers).map(parasMap).context(context).encoding(encoding));
	}
	/**
	 * 以Post方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String post(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.POST));
	}
	
	/**
	 * 以Put方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param parasMap		请求参数
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String put(HttpClient client, String url, Map<String,Object>parasMap,Header[] headers, HttpContext context,String encoding) throws HttpProcessException {
		return put(HttpConfig.custom().client(client).url(url).headers(headers).map(parasMap).context(context).encoding(encoding));
	}
	/**
	 * 以Put方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String put(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.PUT));
	}
	
	/**
	 * 以Delete方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String delete(HttpClient client, String url, Header[] headers, HttpContext context,String encoding) throws HttpProcessException {
		return delete(HttpConfig.custom().client(client).url(url).headers(headers).context(context).encoding(encoding));
	}
	/**
	 * 以Delete方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String delete(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.DELETE));
	}
	
	/**
	 * 以Patch方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param parasMap		请求参数
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String patch(HttpClient client, String url, Map<String,Object>parasMap, Header[] headers, HttpContext context,String encoding) throws HttpProcessException {
		return patch(HttpConfig.custom().client(client).url(url).headers(headers).map(parasMap).context(context).encoding(encoding));
	}
	/**
	 * 以Patch方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String patch(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.PATCH));
	}
	
	/**
	 * 以Head方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String head(HttpClient client, String url, Header[] headers, HttpContext context,String encoding) throws HttpProcessException {
		return head(HttpConfig.custom().client(client).url(url).headers(headers).context(context).encoding(encoding));
	}
	/**
	 * 以Head方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String head(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.HEAD));
	}
	
	/**
	 * 以Options方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String options(HttpClient client, String url, Header[] headers, HttpContext context,String encoding) throws HttpProcessException {
		return options(HttpConfig.custom().client(client).url(url).headers(headers).context(context).encoding(encoding));
	}
	/**
	 * 以Options方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String options(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.OPTIONS));
	}
	
	/**
	 * 以Trace方式,请求资源或服务
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String trace(HttpClient client, String url, Header[] headers, HttpContext context, String encoding) throws HttpProcessException {
		return trace(HttpConfig.custom().client(client).url(url).headers(headers).context(context).encoding(encoding));
	}
	/**
	 * 以Trace方式,请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String trace(HttpConfig config) throws HttpProcessException {
		return send(config.method(HttpMethods.TRACE));
	}
	
	/**
	 * 下载文件
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @param out			输出流
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static OutputStream down(HttpClient client, String url, Header[] headers, HttpContext context, OutputStream out) throws HttpProcessException {
		return down(HttpConfig.custom().client(client).url(url).headers(headers).context(context).out(out));
	}
	
	/**
	 * 下载文件
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static OutputStream down(HttpConfig config) throws HttpProcessException {
		if(config.method() == null) {
			config.method(HttpMethods.GET);
		}
		return fmt2Stream(execute(config), config.out());
	}
	
	/**
	 * 上传文件
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String upload(HttpClient client, String url, Header[] headers, HttpContext context) throws HttpProcessException {
		return upload(HttpConfig.custom().client(client).url(url).headers(headers).context(context));
	}
	
	/**
	 * 上传文件
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static String upload(HttpConfig config) throws HttpProcessException {
		if(config.method() != HttpMethods.POST  && config.method() != HttpMethods.PUT){
			config.method(HttpMethods.POST);
		}
		return send(config);
	}
	
	/**
	 * 查看资源链接情况,返回状态码
	 * 
	 * @param client		client对象
	 * @param url			资源地址
	 * @param headers		请求头信息
	 * @param context		http上下文,用于cookie操作
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static int status(HttpClient client, String url, Header[] headers, HttpContext context, HttpMethods method) throws HttpProcessException {
		return status(HttpConfig.custom().client(client).url(url).headers(headers).context(context).method(method));
	}
	
	/**
	 * 查看资源链接情况,返回状态码
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	public static int status(HttpConfig config) throws HttpProcessException {
		return fmt2Int(execute(config));
	}

	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	
	/**
	 * 请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static String send(HttpConfig config) throws HttpProcessException {
		return fmt2String(execute(config), config.outenc());
	}
	
	/**
	 * 请求资源或服务,返回HttpResult对象
	 * 
	 * @param config		请求参数配置
	 * @return				返回HttpResult处理结果
	 * @throws HttpProcessException	http处理异常
	 */
	public static HttpResult sendAndGetResp(HttpConfig config) throws HttpProcessException {
		Header[] reqHeaders = config.headers();
		//执行结果
		HttpResponse resp =  execute(config);
		
		HttpResult result = new HttpResult(resp);
		result.setResult(fmt2String(resp, config.outenc()));
		result.setReqHeaders(reqHeaders);
		
		return result;
	}
	
	/**
	 * 请求资源或服务
	 * 
	 * @param config		请求参数配置
	 * @return				返回HttpResponse对象
	 * @throws HttpProcessException	http处理异常 
	 */
	private static HttpResponse execute(HttpConfig config) throws HttpProcessException {
		create(config);//获取链接
		HttpResponse resp = null;

		try {
			//创建请求对象
			HttpRequestBase request = getRequest(config.url(), config.method());
			
			//设置超时
			request.setConfig(config.requestConfig());
			
			//设置header信息
			request.setHeaders(config.headers());
			
			//判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
			if(HttpEntityEnclosingRequestBase.class.isAssignableFrom(request.getClass())){
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
				
				if(request.getClass()==HttpGet.class) {
					//检测url中是否存在参数
					//注:只有get请求,才自动截取url中的参数,post等其他方式,不再截取
					config.url(Utils.checkHasParas(config.url(), nvps, config.inenc()));
				}
				
				//装填参数
				HttpEntity entity = Utils.map2HttpEntity(nvps, config.map(), config.inenc());
				
				//设置参数到请求对象中
				((HttpEntityEnclosingRequestBase)request).setEntity(entity);
				
				Utils.info("请求地址:"+config.url());
				if(nvps.size()>0){
					Utils.info("请求参数:"+nvps.toString());
				}
				if(config.json()!=null){
					Utils.info("请求参数:"+config.json());
				}
			}else{
				int idx = config.url().indexOf("?");
				Utils.info("请求地址:"+config.url().substring(0, (idx>0 ? idx : config.url().length())));
				if(idx>0){
					Utils.info("请求参数:"+config.url().substring(idx+1));
				}
			}
			//执行请求操作,并拿到结果(同步阻塞)
			resp = (config.context()==null)?config.client().execute(request) : config.client().execute(request, config.context()) ;

			if(config.isReturnRespHeaders()){
				//获取所有response的header信息
				config.headers(resp.getAllHeaders());
			}
			
			//获取结果实体
			return resp;
			
		} catch (IOException e) {
			throw new HttpProcessException(e);
		}
	}
	
	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	//-----------华----丽----分----割----线--------------
	
	/**
	 * 转化为字符串
	 * 
	 * @param resp			响应对象
	 * @param encoding		编码
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	private static String fmt2String(HttpResponse resp, String encoding) throws HttpProcessException {
		String body = "";
		try {
			if (resp.getEntity() != null) {
				// 按指定编码转换结果实体为String类型
				body = EntityUtils.toString(resp.getEntity(), encoding);
				Utils.info(body);
			}else{//有可能是head请求
				body =resp.getStatusLine().toString();
			}
			EntityUtils.consume(resp.getEntity());
		} catch (IOException e) {
			throw new HttpProcessException(e);
		}finally{			
			close(resp);
		}
		return body;
	}
	
	/**
	 * 转化为数字
	 * 
	 * @param resp			响应对象
	 * @return				返回处理结果
	 * @throws HttpProcessException	http处理异常 
	 */
	private static int fmt2Int(HttpResponse resp) throws HttpProcessException {
		int statusCode;
		try {
			statusCode = resp.getStatusLine().getStatusCode();
			EntityUtils.consume(resp.getEntity());
		} catch (IOException e) {
			throw new HttpProcessException(e);
		}finally{			
			close(resp);
		}
		return statusCode;
	}
	
	/**
	 * 转化为流
	 * 
	 * @param resp			响应对象
	 * @param out			输出流
	 * @return				返回输出流
	 * @throws HttpProcessException	http处理异常 
	 */
	public static OutputStream fmt2Stream(HttpResponse resp, OutputStream out) throws HttpProcessException {
		try {
			resp.getEntity().writeTo(out);
			EntityUtils.consume(resp.getEntity());
		} catch (IOException e) {
			throw new HttpProcessException(e);
		}finally{
			close(resp);
		}
		return out;
	}
	
	/**
	 * 根据请求方法名,获取request对象
	 * 
	 * @param url			资源地址
	 * @param method		请求方式
	 * @return				返回Http处理request基类
	 */
	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) {
			Utils.exception(e);
		}
	}
}

使用方式很简单,可详见https://github.com/Arronlong/httpclientutil。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值