HttpClient4.5.6的Fluent工具集

本文参考自 整理HttpClient4.5的Fluent API的用法 ,如有侵权,请作者联系删除。

MAVEN依赖

<!-- java端模拟浏览器发送请求 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.5.6</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.6</version>
</dependency>
<!-- 工具集 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>1.7</version>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0-jre</version>
</dependency>
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

fluent静态工具类

package vip.coinbag.managemoneymatters.common.http;

import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 

类描述:Apache HttpClient Fluent快速发送GET/POST访问,目前不支持需要登录的操作,待后续完善。

* @author wzx * @time 2018/11/1 */
public class HttpFluent { private static final Logger LOGGER = LoggerFactory.getLogger(HttpFluent.class); private static final Integer CONNECT_TIMEOUT = 5000; // 连接超时5s private static final Integer SOCKET_TIMEOUT = 30000; // 数据传输超时30s /** *

功能描述:无参数的GET请求。

*

jl

* @param url * @since JDK1.8 *

创建日期:2018/11/2 14:37。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String doGet(String url) { Args.notNull(url, "url"); try { return Request.Get(url).connectTimeout(CONNECT_TIMEOUT).socketTimeout(SOCKET_TIMEOUT).execute().returnContent().asString(Consts.UTF_8); } catch (IOException e) { e.printStackTrace(); LOGGER.error(e.getMessage(), e.toString()); } return null; } /** *

功能描述:带参数的GET请求。

*

jl

* @param url * @param params * @since JDK1.8 *

创建日期:2018/11/2 14:39。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String doGet(String url, Object params) { return executeGet(url, null, null, null, params); } /** *

功能描述:设置代理的 GET 请求。

*

jl

* @param url * @param hostName * @param port * @param schemeName * @param params * @since JDK1.8 *

创建日期:2018/11/2 17:34。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String doGet(String url, String hostName, Integer port, String schemeName, Object params) { return executeGet(url, hostName, port, schemeName, params); } /** *

功能描述:执行 GET 请求。

*

jl

* @param url * @param hostName * @param port * @param schemeName * @param params * @since JDK1.8 *

创建日期:2018/11/2 17:35。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
private static String executeGet(String url, String hostName, Integer port, String schemeName, Object params) { if (StringUtils.isEmpty(url)) { return null; } url = buildGetParam(url, params); Request request = Request.Get(url).connectTimeout(CONNECT_TIMEOUT).socketTimeout(SOCKET_TIMEOUT); request = buildProxy(request, hostName, port, schemeName); try { return request.execute().returnContent().asString(Consts.UTF_8); } catch (IOException e) { e.printStackTrace(); LOGGER.error(e.getMessage(), e.toString()); } return null; } /** *

功能描述:构建 GET 参数。

*

jl

* @param url * @param params * @since JDK1.8 *

创建日期:2018/11/2 16:52。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
private static String buildGetParam(String url, Object params) { if (params != null) { //拼接参数 url += "?" + URLEncodedUtilsPerfect.format(params, Consts.UTF_8); } return url; } /** *

功能描述:不带参数的 POST 请求。

*

jl

* @param url * @since JDK1.8 *

创建日期:2018/11/2 17:36。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String doPost(String url) { return doPost(url, null, null, null, null, null); } /** *

功能描述:发送json格式的post请求。

*

jl

* @param url * @param jsonData * @since JDK1.8 *

创建日期:2018/11/1 16:45。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String doPost(String url, String jsonData) { if (StringUtils.isEmpty(jsonData)) { return doPost(url); } Request request = Request.Post(url).connectTimeout(CONNECT_TIMEOUT).socketTimeout(SOCKET_TIMEOUT).bodyString(jsonData, ContentType.APPLICATION_JSON); try { return request.execute().returnContent().asString(Consts.UTF_8); } catch (IOException e) { e.printStackTrace(); LOGGER.error(e.getMessage(), e.toString()); } return null; } public static String doPost(String url, Object params) { return doPost(url, null, null, null, params, null); } public static void doPost(String url, Object params, List<File> files) { doPost(url, null, null, null, params, files); } public static String doPost(String url, String hostName, Integer port, String schemeName, Object params, List<File> files) { return executePost(url, hostName, port, schemeName, params, files); } private static String executePost(String url, String hostName, Integer port, String schemeName, Object params, List<File> files) { if (StringUtils.isEmpty(url)) { return null; } HttpEntity entity = buildPostParam(params, files); /** * Content type 'application/x-www-form-urlencoded' * 这是默认的不设置contentType时的请求头,那么在controller层接收的时候就要用 @RequestParam FirstProject firstProject * 这样的响应头来接收 * 如果controller层用 @RequestBody FirstProject firstProject 这样的格式来接收,那么contentType应该设为 'application/json' * 传输数据的格式应该是json格式的,可以调用 doPost(String url, String jsonData)方法 */ Request request = Request.Post(url).connectTimeout(CONNECT_TIMEOUT).socketTimeout(SOCKET_TIMEOUT).body(entity); request = buildProxy(request, hostName, port, schemeName); try { return request.execute().returnContent().asString(Consts.UTF_8); } catch (IOException e) { e.printStackTrace(); LOGGER.error(e.getMessage(), e.toString()); } return null; } /** * 构建POST方法请求参数 * @return */ private static HttpEntity buildPostParam(Object params, List<File> files) { if(params == null && CollectionUtils.isEmpty(files)) { return null; } if(CollectionUtils.isNotEmpty(files)) { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); for (File file : files) { /** * 在接收文件的响应头中默认是这样写的 @RequestParam List file * 其实这样写默认接收响应头name为file的文件,即接收文件参数其实是这样的 @RequestParam("file") List file * 所以addBinaryBody的name应该设为file,但是可根据自己接收参数的设置做相应修改 */ builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName()); } if (params != null) { if (params instanceof Map) { Map map = (Map) params; for (Object key : map.keySet()) { if (key == null || map.get(key) == null) { continue; } builder.addTextBody(key.toString(), map.get(key).toString(), ContentType.create("text/plain", Consts.UTF_8)); } } else if (params instanceof List) { List list = (List) params; if (list.get(0) instanceof NameValuePair) { List<NameValuePair> nameValuePairs = list; for (NameValuePair nameValuePair : nameValuePairs) { //设置ContentType为UTF-8,默认为text/plain; charset=ISO-8859-1,传递中文参数会乱码 builder.addTextBody(nameValuePair.getName(), nameValuePair.getValue(), ContentType.create("text/plain", Consts.UTF_8)); } } } else { // 参数类型为 javaBean // Object 转 Map 类型 Map map = new BeanMap(params); for (Object key : map.keySet()) { if (key == null || map.get(key) == null) { continue; } builder.addTextBody(key.toString(), map.get(key).toString(), ContentType.create("text/plain", Consts.UTF_8)); } } } return builder.build(); } else { return new UrlEncodedFormEntityPerfect(params, Consts.UTF_8); } } /** * 设置代理 * @param request * @param hostName * @param port * @param schemeName * @return */ private static Request buildProxy(Request request, String hostName, Integer port, String schemeName) { if(StringUtils.isNotEmpty(hostName) && port != null) { //设置代理 if (StringUtils.isEmpty(schemeName)) { schemeName = HttpHost.DEFAULT_SCHEME_NAME; } request.viaProxy(new HttpHost(hostName, port, schemeName)); } return request; } }

URLEncodedUtils工具类完善

URLEncodedUtils工具类只提供了List集合的参数调用,所以我们继承该类,并完成Map和JavaBean的参数调用

package vip.coinbag.managemoneymatters.common.http;

import org.apache.commons.beanutils.BeanMap;
import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.util.Args;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

/**
 * 

类描述:。

* * @author jl * @version v1.0.0.1。 * @since JDK1.8。 *

创建日期:2018/11/2 15:12。

*/
public class URLEncodedUtilsPerfect extends URLEncodedUtils { private static final char QP_SEP_A = '&'; private static final String NAME_VALUE_SEPARATOR = "="; /** *

功能描述:构造参数。

*

jl

* @param parameters * @param charset * @since JDK1.8 *

创建日期:2018/11/2 17:09。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String format( final Object parameters, final Charset charset) { if (parameters == null) { return ""; } if (parameters instanceof Map) { // 参数类型为 Map Map map = (Map) parameters; return format(map, QP_SEP_A, charset != null ? charset : Consts.UTF_8); } else if ((parameters instanceof List)) { List list = (List) parameters; if (list.get(0) instanceof NameValuePair) { // 参数类型为 List List<NameValuePair> nameValuePairs = list; return format(nameValuePairs, charset != null ? charset : Consts.UTF_8); } return ""; } else { // 参数类型为 javaBean // Object 转 Map 类型 Map map = new BeanMap(parameters); return format(map, QP_SEP_A, charset != null ? charset : Consts.UTF_8); } } /** *

功能描述:构造参数类型为 Map 的参数。

*

jl

* @param parameters * @param parameterSeparator * @param charset * @since JDK1.8 *

创建日期:2018/11/2 17:23。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
public static String format( final Map parameters, final char parameterSeparator, final Charset charset) { Args.notNull(parameters, "Parameters"); final StringBuilder result = new StringBuilder(); for (final Object key : parameters.keySet()) { try { final String encodedName = encodeFormFields(key, charset.toString()); final String encodedValue = encodeFormFields(parameters.get(key), charset.toString()); if (result.length() > 0) { result.append(parameterSeparator); } if (StringUtils.isEmpty(encodedName) || StringUtils.isEmpty(encodedValue)) { continue; } result.append(encodedName); if (encodedValue != null) { result.append(NAME_VALUE_SEPARATOR); result.append(encodedValue); } } catch (Exception e) { e.printStackTrace(); } } return result.toString(); } /** *

功能描述:参数编码。

*

jl

* @param content * @param charset * @since JDK1.8 *

创建日期:2018/11/2 17:22。

*

更新日期:[日期YYYY-MM-DD][更改人姓名][变更描述]。

*/
private static String encodeFormFields(final Object content, final String charset) throws UnsupportedEncodingException { if (content == null) { return null; } return URLEncoder.encode(content.toString(), charset); } }

UrlEncodedFormEntity工具类完善

在构造post参数时同样只提供了List参数,所以跳过该类,直接继承该类的父类StringEntity,并结合上面的URLEncodedUtilsPerfect完成对Map和JavaBean的参数构造

package vip.coinbag.managemoneymatters.common.http;

import org.apache.http.Consts;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;

import java.nio.charset.Charset;

/**
 * 

类描述:。

* * @author jl * @version v1.0.0.1。 * @since JDK1.8。 *

创建日期:2018/11/2 17:40。

*/
public class UrlEncodedFormEntityPerfect extends StringEntity { public UrlEncodedFormEntityPerfect(final Object parameters, final Charset charset) { super(URLEncodedUtilsPerfect.format(parameters, charset != null ? charset : Consts.UTF_8), ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset != null ? charset : Consts.UTF_8)); } }

你可能感兴趣的:(http)