richie
5 years ago
10 changed files with 1464 additions and 0 deletions
@ -0,0 +1,677 @@
|
||||
package com.fanruan.api.net.http; |
||||
|
||||
import com.fanruan.api.consts.EncodeConstantsKit; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.net.http.rs.BaseHttpResponseHandle; |
||||
import com.fanruan.api.net.http.rs.HttpRequest; |
||||
import com.fanruan.api.net.http.rs.HttpRequestType; |
||||
import com.fanruan.api.net.http.rs.HttpResponseType; |
||||
import com.fanruan.api.net.http.rs.StreamResponseHandle; |
||||
import com.fanruan.api.net.http.rs.TextResponseHandle; |
||||
import com.fanruan.api.net.http.rs.UploadResponseHandle; |
||||
import com.fr.third.guava.collect.Maps; |
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.HttpEntityEnclosingRequest; |
||||
import com.fr.third.org.apache.http.HttpHost; |
||||
import com.fr.third.org.apache.http.NameValuePair; |
||||
import com.fr.third.org.apache.http.NoHttpResponseException; |
||||
import com.fr.third.org.apache.http.client.HttpRequestRetryHandler; |
||||
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.client.methods.HttpEntityEnclosingRequestBase; |
||||
import com.fr.third.org.apache.http.client.methods.HttpRequestBase; |
||||
import com.fr.third.org.apache.http.client.protocol.HttpClientContext; |
||||
import com.fr.third.org.apache.http.client.utils.URIBuilder; |
||||
import com.fr.third.org.apache.http.config.Registry; |
||||
import com.fr.third.org.apache.http.config.RegistryBuilder; |
||||
import com.fr.third.org.apache.http.conn.routing.HttpRoute; |
||||
import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.socket.LayeredConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.entity.FileEntity; |
||||
import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode; |
||||
import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder; |
||||
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||
import com.fr.third.org.apache.http.impl.client.HttpClients; |
||||
import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
import com.fr.third.org.apache.http.message.BasicNameValuePair; |
||||
import com.fr.third.org.apache.http.protocol.HttpContext; |
||||
import com.fr.third.org.apache.http.ssl.SSLContexts; |
||||
import org.jetbrains.annotations.NotNull; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLException; |
||||
import javax.net.ssl.SSLHandshakeException; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.io.InterruptedIOException; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
import java.net.URLEncoder; |
||||
import java.net.UnknownHostException; |
||||
import java.nio.charset.Charset; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import static com.fanruan.api.net.http.rs.HttpRequestType.POST; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
* <p> |
||||
* http请求工具类,封装了用于http请求的各种方法 |
||||
* </p> |
||||
*/ |
||||
public class HttpKit { |
||||
|
||||
private static final int RETRY_TIMES = 5; |
||||
|
||||
private static CloseableHttpClient httpClient = null; |
||||
|
||||
private final static Object SYNC_LOCK = new Object(); |
||||
|
||||
/** |
||||
* 根据请求地址创建HttpClient对象 |
||||
* |
||||
* @param url 请求地址 |
||||
* @return HttpClient对象 |
||||
*/ |
||||
public static CloseableHttpClient getHttpClient(String url) { |
||||
String hostname = url.split("/")[2]; |
||||
int port = 80; |
||||
if (hostname.contains(":")) { |
||||
String[] arr = hostname.split(":"); |
||||
hostname = arr[0]; |
||||
port = Integer.parseInt(arr[1]); |
||||
} |
||||
if (httpClient == null) { |
||||
synchronized (SYNC_LOCK) { |
||||
if (httpClient == null) { |
||||
httpClient = createHttpClient(hostname, port, SSLContexts.createDefault()); |
||||
} |
||||
} |
||||
} |
||||
return httpClient; |
||||
} |
||||
|
||||
|
||||
public static CloseableHttpClient createHttpClient(String hostname, int port, SSLContext sslContext) { |
||||
return createHttpClient(200, 40, 100, hostname, port, sslContext); |
||||
} |
||||
|
||||
private static CloseableHttpClient createHttpClient(int maxTotal, |
||||
int maxPerRoute, |
||||
int maxRoute, |
||||
String hostname, |
||||
int port, |
||||
SSLContext sslContext) { |
||||
ConnectionSocketFactory socketFactory = PlainConnectionSocketFactory.getSocketFactory(); |
||||
LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext); |
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder |
||||
.<ConnectionSocketFactory>create() |
||||
.register("http", socketFactory) |
||||
.register("https", sslConnectionSocketFactory) |
||||
.build(); |
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); |
||||
// 将最大连接数增加
|
||||
cm.setMaxTotal(maxTotal); |
||||
// 将每个路由基础的连接增加
|
||||
cm.setDefaultMaxPerRoute(maxPerRoute); |
||||
HttpHost httpHost = new HttpHost(hostname, port); |
||||
// 将目标主机的最大连接数增加
|
||||
cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute); |
||||
|
||||
// 请求重试处理
|
||||
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { |
||||
@Override |
||||
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { |
||||
if (executionCount >= RETRY_TIMES) {// 如果已经重试了5次,就放弃
|
||||
return false; |
||||
} |
||||
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
|
||||
return true; |
||||
} |
||||
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
|
||||
return false; |
||||
} |
||||
if (exception instanceof InterruptedIOException) {// 超时
|
||||
return false; |
||||
} |
||||
if (exception instanceof UnknownHostException) {// 目标服务器不可达
|
||||
return false; |
||||
} |
||||
if (exception instanceof SSLException) {// SSL握手异常
|
||||
return false; |
||||
} |
||||
|
||||
HttpClientContext clientContext = HttpClientContext.adapt(context); |
||||
com.fr.third.org.apache.http.HttpRequest request = clientContext.getRequest(); |
||||
// 如果请求是幂等的,就再次尝试
|
||||
return !(request instanceof HttpEntityEnclosingRequest); |
||||
} |
||||
}; |
||||
|
||||
return HttpClients.custom() |
||||
.setConnectionManager(cm) |
||||
.setRetryHandler(httpRequestRetryHandler) |
||||
.build(); |
||||
} |
||||
|
||||
/** |
||||
* 设置 httpEntity |
||||
* |
||||
* @param requestBase 请求体 |
||||
* @param httpRequest 请求 |
||||
*/ |
||||
private static void setHttpEntity(@NotNull HttpEntityEnclosingRequestBase requestBase, @NotNull HttpRequest httpRequest) { |
||||
HttpEntity httpEntity = httpRequest.getHttpEntity(); |
||||
if (httpEntity != null) { |
||||
// 如果存在 httpEntity 直接设置
|
||||
requestBase.setEntity(httpEntity); |
||||
return; |
||||
} |
||||
Map<String, String> params = httpRequest.getParams(); |
||||
if (params == null || params.isEmpty()) { |
||||
return; |
||||
} |
||||
List<NameValuePair> pairs = new ArrayList<NameValuePair>(); |
||||
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); |
||||
} |
||||
try { |
||||
requestBase.setEntity(new UrlEncodedFormEntity(pairs, httpRequest.getEncoding())); |
||||
} catch (UnsupportedEncodingException e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
private static <V> Map<String, String> transformMap(Map<String, V> oldMap) { |
||||
if (oldMap == null) { |
||||
return null; |
||||
} |
||||
return Maps.transformEntries(oldMap, new Maps.EntryTransformer<String, V, String>() { |
||||
@Override |
||||
public String transformEntry(@Nullable String key, @Nullable V value) { |
||||
return value == null ? null : value.toString(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static <V> String post(String url, Map<String, V> params) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseType 返回类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <T, V> T post(String url, Map<String, V> params, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build()); |
||||
return responseType.result(response, null); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param headers 请求头 |
||||
* @param responseType 返回类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <T, V> T post(String url, Map<String, V> params, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build()); |
||||
return responseType.result(response, null); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param paramsEncoding 参数编码 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.encoding(paramsEncoding) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param paramsEncoding 参数编码 |
||||
* @param headers 请求头 |
||||
* @param responseType 返回值类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
public static <T, V> T post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.encoding(paramsEncoding) |
||||
.headers(headers) |
||||
.build()); |
||||
return responseType.result(response, responseEncoding); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static String get(String url) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static String get(String url, Map<String, String> params) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).params(params).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).params(params).headers(headers).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param responseEncoding 返回的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, String responseEncoding) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param responseEncoding 返回的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 从指定的地址下载文件 |
||||
* @param url 文件下载地址 |
||||
* @return 文件的字节流 |
||||
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||
*/ |
||||
public static ByteArrayInputStream download(String url) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).build(), StreamResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 从指定的地址下载文件 |
||||
* @param url 文件下载地址 |
||||
* @param params 参数对 |
||||
* @param responseEncoding 响应的文件编码 |
||||
* @param headers 请求头 |
||||
* @return 文件的字节流 |
||||
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||
*/ |
||||
public static ByteArrayInputStream download(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.headers(headers) |
||||
.build(), |
||||
new StreamResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param file 要上传的文件,默认的文件编码为utf-8 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, File file) throws IOException { |
||||
upload(url, file, Charset.forName("utf-8")); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param file 要上传的文件 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, File file, Charset charset) throws IOException { |
||||
upload(url, new FileEntity(file), charset); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param builder 附件构造器 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, MultipartEntityBuilder builder, Charset charset) throws IOException { |
||||
upload(url, builder, charset, Collections.<String, String>emptyMap(), POST); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param fileEntity 文件实体 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, FileEntity fileEntity, Charset charset) throws IOException { |
||||
upload(url, fileEntity, charset, Collections.<String, String>emptyMap(), POST); |
||||
} |
||||
|
||||
/** |
||||
* 上传多文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param builder 附件构造器 |
||||
* @param charset 文件的编码 |
||||
* @param headers 请求头 |
||||
* @param httpRequestType 请求类型 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, MultipartEntityBuilder builder, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||
// richie:采用浏览器模式,防止出现乱码
|
||||
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); |
||||
HttpEntity reqEntity = builder.setCharset(charset).build(); |
||||
upload(url, reqEntity, charset, headers, httpRequestType); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param reqEntity 请求实体 |
||||
* @param charset 文件的编码 |
||||
* @param headers 请求头 |
||||
* @param httpRequestType 请求类型 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, HttpEntity reqEntity, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||
executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.headers(headers) |
||||
.method(httpRequestType) |
||||
.httpEntity(reqEntity) |
||||
.encoding(charset.toString()) |
||||
.build(), |
||||
UploadResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,使用默认文本http解析器,UTF-8编码 |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static String executeAndParse(HttpRequest httpRequest) throws IOException { |
||||
return executeAndParse(httpRequest, TextResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,自请求参数,并指定 http 响应处理器 |
||||
* 例: |
||||
* <pre> |
||||
* String res = HttpToolbox.executeAndParse(HttpRequest |
||||
* .custom() |
||||
* .url("") |
||||
* .build(), |
||||
* TextResponseHandle.DEFAULT); |
||||
* </pre> |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @param handle http 解析器 |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static <T> T executeAndParse(HttpRequest httpRequest, BaseHttpResponseHandle<T> handle) throws IOException { |
||||
return handle.parse(execute(httpRequest)); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,传入请求参数 |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static CloseableHttpResponse execute(HttpRequest httpRequest) throws IOException { |
||||
return execute(getHttpClient(httpRequest.getUrl()), httpRequest); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,自定义client对象,传入请求参数 |
||||
* |
||||
* @param httpClient http客户端 |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static CloseableHttpResponse execute(CloseableHttpClient httpClient, HttpRequest httpRequest) throws IOException { |
||||
String url = httpRequest.getUrl(); |
||||
|
||||
// 创建请求对象
|
||||
HttpRequestBase httpRequestBase = httpRequest.getMethod().createHttpRequest(url); |
||||
|
||||
// 设置header信息
|
||||
httpRequestBase.setHeader("User-Agent", "Mozilla/5.0"); |
||||
Map<String, String> headers = httpRequest.getHeaders(); |
||||
if (headers != null && !headers.isEmpty()) { |
||||
for (Map.Entry<String, String> entry : headers.entrySet()) { |
||||
httpRequestBase.setHeader(entry.getKey(), entry.getValue()); |
||||
} |
||||
} |
||||
|
||||
// 配置请求的设置
|
||||
RequestConfig requestConfig = httpRequest.getConfig(); |
||||
if (requestConfig != null) { |
||||
httpRequestBase.setConfig(requestConfig); |
||||
} |
||||
|
||||
// 判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
|
||||
if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(httpRequestBase.getClass())) { |
||||
setHttpEntity((HttpEntityEnclosingRequestBase) httpRequestBase, httpRequest); |
||||
} else { |
||||
Map<String, String> params = httpRequest.getParams(); |
||||
if (params != null && !params.isEmpty()) { |
||||
// 注意get等不支持设置entity需要更新拼接之后的URL,但是url变量没有更新
|
||||
httpRequestBase.setURI(URI.create(buildUrl(url, params, httpRequest.getEncoding()))); |
||||
} |
||||
} |
||||
|
||||
return httpClient.execute(httpRequestBase); |
||||
} |
||||
|
||||
/** |
||||
* 构建 Url |
||||
* |
||||
* @param url 请求地址 |
||||
* @param params 参数 |
||||
* @return 拼接之后的地址 |
||||
*/ |
||||
public static String buildUrl(String url, Map<String, String> params) { |
||||
try { |
||||
return buildUrl(url, params, EncodeConstantsKit.ENCODING_UTF_8); |
||||
} catch (UnsupportedEncodingException ignore) { |
||||
} |
||||
return url; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 构建 Url |
||||
* |
||||
* @param url 请求地址 |
||||
* @param params 参数 |
||||
* @return 拼接之后的地址 |
||||
* @throws UnsupportedEncodingException 不支持的编码 |
||||
*/ |
||||
private static String buildUrl(String url, Map<String, String> params, String paramsEncoding) throws UnsupportedEncodingException { |
||||
if (params == null || params.isEmpty()) { |
||||
return url; |
||||
} |
||||
URIBuilder builder; |
||||
try { |
||||
builder = new URIBuilder(url); |
||||
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||
String key = URLEncoder.encode(entry.getKey(), paramsEncoding); |
||||
String value = URLEncoder.encode(entry.getValue(), paramsEncoding); |
||||
builder.setParameter(key, value); |
||||
} |
||||
return builder.build().toString(); |
||||
} catch (URISyntaxException e) { |
||||
LogKit.debug("Error to build url, please check the arguments."); |
||||
} |
||||
return url; |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.stable.EncodeConstants; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* http 结果解析器 |
||||
* |
||||
* @author vito |
||||
* @date 2019-07-14 |
||||
*/ |
||||
public abstract class BaseHttpResponseHandle<T> { |
||||
|
||||
/** |
||||
* 解析编码,默认为 UTF_8 |
||||
*/ |
||||
private String encoding = EncodeConstants.ENCODING_UTF_8; |
||||
|
||||
public BaseHttpResponseHandle() { |
||||
} |
||||
|
||||
public BaseHttpResponseHandle(String encoding) { |
||||
this.encoding = encoding; |
||||
} |
||||
|
||||
/** |
||||
* 获取解析编码 |
||||
* |
||||
* @return 解析编码 |
||||
*/ |
||||
public String getEncoding() { |
||||
return encoding; |
||||
} |
||||
|
||||
/** |
||||
* 设置解析编码 |
||||
* |
||||
* @param encoding 解析编码 |
||||
*/ |
||||
public void setEncoding(String encoding) { |
||||
this.encoding = encoding; |
||||
} |
||||
|
||||
/** |
||||
* 解析响应结果 |
||||
* |
||||
* @param response 响应 |
||||
* @return 解析结果 |
||||
* @throws IOException io异常 |
||||
*/ |
||||
public abstract T parse(CloseableHttpResponse response) throws IOException; |
||||
} |
@ -0,0 +1,215 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fanruan.api.consts.EncodeConstantsKit; |
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||
import org.jetbrains.annotations.NotNull; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
*/ |
||||
public class HttpRequest { |
||||
|
||||
private static final int TIME_OUT = 10 * 1000; |
||||
private static final RequestConfig DEFAULT = RequestConfig |
||||
.custom() |
||||
.setConnectionRequestTimeout(TIME_OUT) |
||||
.setConnectTimeout(TIME_OUT) |
||||
.setSocketTimeout(TIME_OUT) |
||||
.build(); |
||||
/** |
||||
* 请求地址 |
||||
*/ |
||||
private String url; |
||||
|
||||
/** |
||||
* 请求头 |
||||
*/ |
||||
private Map<String, String> headers; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
private Map<String, String> params; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
* |
||||
* @see RequestConfig |
||||
*/ |
||||
@Nullable |
||||
private RequestConfig config; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
* |
||||
* @see HttpEntity |
||||
*/ |
||||
@Nullable |
||||
private HttpEntity httpEntity; |
||||
|
||||
/** |
||||
* 请求方法 |
||||
*/ |
||||
private HttpRequestType method; |
||||
|
||||
/** |
||||
* 参数字符集 |
||||
*/ |
||||
private String encoding; |
||||
|
||||
private HttpRequest(Builder builder) { |
||||
this.url = builder.url; |
||||
this.headers = builder.headers; |
||||
this.params = builder.params; |
||||
this.config = builder.config; |
||||
this.encoding = builder.encoding; |
||||
this.httpEntity = builder.httpEntity; |
||||
this.method = builder.method; |
||||
} |
||||
|
||||
public String getUrl() { |
||||
return url; |
||||
} |
||||
|
||||
public Map<String, String> getHeaders() { |
||||
return headers; |
||||
} |
||||
|
||||
public Map<String, String> getParams() { |
||||
return params; |
||||
} |
||||
|
||||
public RequestConfig getConfig() { |
||||
return config; |
||||
} |
||||
|
||||
public String getEncoding() { |
||||
return encoding; |
||||
} |
||||
|
||||
public HttpEntity getHttpEntity() { |
||||
return httpEntity; |
||||
} |
||||
|
||||
public HttpRequestType getMethod() { |
||||
return method; |
||||
} |
||||
|
||||
public static Builder custom() { |
||||
return new Builder(); |
||||
} |
||||
|
||||
public static final class Builder { |
||||
private String url; |
||||
private Map<String, String> headers = Collections.emptyMap(); |
||||
private Map<String, String> params = Collections.emptyMap(); |
||||
@Nullable |
||||
private RequestConfig config = DEFAULT; |
||||
@Nullable |
||||
private HttpEntity httpEntity; |
||||
private String encoding = EncodeConstantsKit.ENCODING_UTF_8; |
||||
private HttpRequestType method = HttpRequestType.GET; |
||||
|
||||
private Builder() { |
||||
} |
||||
|
||||
public HttpRequest build() { |
||||
if (this.url == null) { |
||||
throw new IllegalStateException("url == null"); |
||||
} |
||||
return new HttpRequest(this); |
||||
} |
||||
|
||||
public Builder url(@NotNull String url) { |
||||
if (url == null) { |
||||
throw new NullPointerException("url == null"); |
||||
} |
||||
this.url = url; |
||||
return this; |
||||
} |
||||
|
||||
public Builder headers(Map<String, String> headers) { |
||||
if (headers != null) { |
||||
this.headers = headers; |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Builder params(Map<String, String> params) { |
||||
if (params != null) { |
||||
this.params = params; |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Builder config(RequestConfig config) { |
||||
this.config = config; |
||||
return this; |
||||
} |
||||
|
||||
public Builder get() { |
||||
this.method = HttpRequestType.GET; |
||||
return this; |
||||
} |
||||
|
||||
public Builder post(HttpEntity httpEntity) { |
||||
this.method = HttpRequestType.POST; |
||||
this.httpEntity(httpEntity); |
||||
return this; |
||||
} |
||||
|
||||
public Builder post(Map<String, String> params) { |
||||
this.method = HttpRequestType.POST; |
||||
this.params(params); |
||||
return this; |
||||
} |
||||
|
||||
public Builder put(HttpEntity httpEntity) { |
||||
this.method = HttpRequestType.PUT; |
||||
this.httpEntity(httpEntity); |
||||
return this; |
||||
} |
||||
|
||||
public Builder put(Map<String, String> params) { |
||||
this.method = HttpRequestType.PUT; |
||||
this.params(params); |
||||
return this; |
||||
} |
||||
|
||||
public Builder delete() { |
||||
this.method = HttpRequestType.DELETE; |
||||
return this; |
||||
} |
||||
|
||||
public Builder encoding(String encoding) { |
||||
if (encoding == null) { |
||||
throw new NullPointerException("httpEntity == null"); |
||||
} |
||||
this.encoding = encoding; |
||||
return this; |
||||
} |
||||
|
||||
public Builder httpEntity(HttpEntity httpEntity) { |
||||
this.httpEntity = httpEntity; |
||||
return this; |
||||
} |
||||
|
||||
public Builder method(@NotNull HttpRequestType method) { |
||||
if (method == null) { |
||||
throw new NullPointerException("method == null"); |
||||
} |
||||
this.method = method; |
||||
return this; |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,114 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.third.org.apache.http.client.methods.HttpDelete; |
||||
import com.fr.third.org.apache.http.client.methods.HttpGet; |
||||
import com.fr.third.org.apache.http.client.methods.HttpHead; |
||||
import com.fr.third.org.apache.http.client.methods.HttpOptions; |
||||
import com.fr.third.org.apache.http.client.methods.HttpPatch; |
||||
import com.fr.third.org.apache.http.client.methods.HttpPost; |
||||
import com.fr.third.org.apache.http.client.methods.HttpPut; |
||||
import com.fr.third.org.apache.http.client.methods.HttpRequestBase; |
||||
import com.fr.third.org.apache.http.client.methods.HttpTrace; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
*/ |
||||
public enum HttpRequestType { |
||||
/** |
||||
* 求获取Request-URI所标识的资源 |
||||
*/ |
||||
GET("GET") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpGet(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 |
||||
* POST请求可能会导致新的资源的建立和/或已有资源的修改 |
||||
*/ |
||||
POST("POST") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpPost(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。 |
||||
* 这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息 |
||||
* 只获取响应信息报头 |
||||
*/ |
||||
HEAD("HEAD") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpHead(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 向指定资源位置上传其最新内容(全部更新,操作幂等) |
||||
*/ |
||||
PUT("PUT") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpPut(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 请求服务器删除Request-URI所标识的资源 |
||||
*/ |
||||
DELETE("DELETE") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpDelete(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 请求服务器回送收到的请求信息,主要用于测试或诊断 |
||||
*/ |
||||
TRACE("TRACE") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpTrace(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 向指定资源位置上传其最新内容(部分更新,非幂等) |
||||
*/ |
||||
PATCH("PATCH") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpPatch(url); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* 返回服务器针对特定资源所支持的HTTP请求方法。 |
||||
* 也可以利用向Web服务器发送'*'的请求来测试服务器的功能性 |
||||
*/ |
||||
OPTIONS("OPTIONS") { |
||||
@Override |
||||
public HttpRequestBase createHttpRequest(String url) { |
||||
return new HttpOptions(url); |
||||
} |
||||
}; |
||||
|
||||
public abstract HttpRequestBase createHttpRequest(String url); |
||||
|
||||
private String name; |
||||
|
||||
HttpRequestType(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
} |
@ -0,0 +1,103 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.client.methods.HttpUriRequest; |
||||
import com.fr.third.org.apache.http.client.protocol.HttpClientContext; |
||||
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||
import com.fr.third.org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
*/ |
||||
public interface HttpResponseType<T> { |
||||
|
||||
/** |
||||
* 处理http响应 |
||||
* |
||||
* @param client 客户端 |
||||
* @param url 地址 |
||||
* @param request 请求 |
||||
* @param charset 字符集 |
||||
* @return 处理之后的响应 |
||||
* @throws IOException 异常 |
||||
*/ |
||||
@Deprecated |
||||
T result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException; |
||||
|
||||
/** |
||||
* 处理http响应 |
||||
* |
||||
* @param response 响应 |
||||
* @param charset 字符集 |
||||
* @return 处理之后的响应 |
||||
* @throws IOException 异常 |
||||
*/ |
||||
T result(CloseableHttpResponse response, String charset) throws IOException; |
||||
|
||||
HttpResponseType<String> TEXT = new HttpResponseType<String>() { |
||||
|
||||
@Override |
||||
public String result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException { |
||||
CloseableHttpResponse response = client.execute(request, HttpClientContext.create()); |
||||
return result(response, charset); |
||||
} |
||||
|
||||
@Override |
||||
public String result(CloseableHttpResponse response, String charset) throws IOException { |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
String result = EntityUtils.toString(entity, charset); |
||||
EntityUtils.consume(entity); |
||||
return result; |
||||
} finally { |
||||
if (response != null) { |
||||
response.close(); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
HttpResponseType<ByteArrayInputStream> STREAM = new HttpResponseType<ByteArrayInputStream>() { |
||||
|
||||
@Override |
||||
public ByteArrayInputStream result(CloseableHttpClient client, String url, HttpUriRequest request, String charset) throws IOException { |
||||
CloseableHttpResponse response = client.execute(request, HttpClientContext.create()); |
||||
return result(response, charset); |
||||
} |
||||
|
||||
@Override |
||||
public ByteArrayInputStream result(CloseableHttpResponse response, String charset) throws IOException { |
||||
InputStream in = null; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity != null) { |
||||
in = entity.getContent(); |
||||
byte[] buff = new byte[8000]; |
||||
int bytesRead; |
||||
ByteArrayOutputStream bao = new ByteArrayOutputStream(); |
||||
while ((bytesRead = in.read(buff)) != -1) { |
||||
bao.write(buff, 0, bytesRead); |
||||
} |
||||
byte[] data = bao.toByteArray(); |
||||
return new ByteArrayInputStream(data); |
||||
} |
||||
return null; |
||||
} finally { |
||||
if (response != null) { |
||||
response.close(); |
||||
} |
||||
if (in != null) { |
||||
in.close(); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,55 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* 流响应解析器 |
||||
* |
||||
* @author vito |
||||
* @date 2019-07-14 |
||||
*/ |
||||
public class StreamResponseHandle extends BaseHttpResponseHandle<ByteArrayInputStream> { |
||||
|
||||
public static final StreamResponseHandle DEFAULT = new StreamResponseHandle(); |
||||
private static final int BUFFER_LENGTH = 8000; |
||||
|
||||
public StreamResponseHandle() { |
||||
} |
||||
|
||||
public StreamResponseHandle(String encoding) { |
||||
super(encoding); |
||||
} |
||||
|
||||
@Override |
||||
public ByteArrayInputStream parse(CloseableHttpResponse response) throws IOException { |
||||
InputStream in = null; |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity != null) { |
||||
in = entity.getContent(); |
||||
byte[] buff = new byte[BUFFER_LENGTH]; |
||||
int bytesRead; |
||||
ByteArrayOutputStream bao = new ByteArrayOutputStream(); |
||||
while ((bytesRead = in.read(buff)) != -1) { |
||||
bao.write(buff, 0, bytesRead); |
||||
} |
||||
byte[] data = bao.toByteArray(); |
||||
return new ByteArrayInputStream(data); |
||||
} |
||||
return null; |
||||
} finally { |
||||
if (response != null) { |
||||
response.close(); |
||||
} |
||||
if (in != null) { |
||||
in.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* 文本响应解析器 |
||||
* |
||||
* @author vito |
||||
* @date 2019-07-14 |
||||
*/ |
||||
public class TextResponseHandle extends BaseHttpResponseHandle<String> { |
||||
|
||||
public static final TextResponseHandle DEFAULT = new TextResponseHandle(); |
||||
|
||||
public TextResponseHandle() { |
||||
} |
||||
|
||||
public TextResponseHandle(String encoding) { |
||||
super(encoding); |
||||
} |
||||
|
||||
@Override |
||||
public String parse(CloseableHttpResponse response) throws IOException { |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
String result = EntityUtils.toString(entity, getEncoding()); |
||||
EntityUtils.consume(entity); |
||||
return result; |
||||
} finally { |
||||
if (response != null) { |
||||
response.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fanruan.api.net.http.rs; |
||||
|
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.HttpStatus; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.util.EntityUtils; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* 上传响应解析器 |
||||
* |
||||
* @author vito |
||||
* @date 2019-07-14 |
||||
*/ |
||||
public class UploadResponseHandle extends BaseHttpResponseHandle<Void> { |
||||
|
||||
public static final UploadResponseHandle DEFAULT = new UploadResponseHandle(); |
||||
|
||||
public UploadResponseHandle() { |
||||
} |
||||
|
||||
public UploadResponseHandle(String encoding) { |
||||
super(encoding); |
||||
} |
||||
|
||||
@Override |
||||
public Void parse(CloseableHttpResponse response) throws IOException { |
||||
try { |
||||
int statusCode = response.getStatusLine().getStatusCode(); |
||||
if (statusCode == HttpStatus.SC_OK) { |
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity != null) { |
||||
EntityUtils.consume(entity); |
||||
} |
||||
} else { |
||||
HttpEntity entity = response.getEntity(); |
||||
String result = EntityUtils.toString(entity, getEncoding()); |
||||
throw new IOException("Connect error, error code:" + statusCode + "; message:" + result); |
||||
} |
||||
} finally { |
||||
if (response != null) { |
||||
response.close(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,153 @@
|
||||
package com.fanruan.api.net.http; |
||||
|
||||
import com.fanruan.api.Prepare; |
||||
import com.fanruan.api.net.http.rs.HttpRequest; |
||||
import com.fanruan.api.net.http.rs.HttpResponseType; |
||||
import com.fanruan.api.net.http.rs.StreamResponseHandle; |
||||
import com.fanruan.api.util.IOKit; |
||||
import com.fr.json.JSONObject; |
||||
import okhttp3.HttpUrl; |
||||
import okhttp3.mockwebserver.MockResponse; |
||||
import okhttp3.mockwebserver.MockWebServer; |
||||
import okhttp3.mockwebserver.RecordedRequest; |
||||
import org.junit.AfterClass; |
||||
import org.junit.Test; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.net.SocketTimeoutException; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertNotNull; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
*/ |
||||
public class HttpKitTest extends Prepare { |
||||
|
||||
private static MockWebServer server = new MockWebServer(); |
||||
|
||||
@AfterClass |
||||
public static void tearDown() throws Exception { |
||||
server.shutdown(); |
||||
} |
||||
|
||||
@Test |
||||
public void testGet() { |
||||
String text = null; |
||||
try { |
||||
text = HttpKit.get("http://www.baidu.com"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
assertNotNull(text); |
||||
} |
||||
|
||||
@Test |
||||
public void testPost() { |
||||
Map<String, String> map = new HashMap<String, String>(); |
||||
map.put("key", "bbs"); |
||||
try { |
||||
String resText = HttpKit.post("https://cloud.fanruan.com/site", map); |
||||
assertEquals("http://bbs.fanruan.com/", new JSONObject(resText).get("value")); |
||||
} catch (SocketTimeoutException ignore) { |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
fail(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testStream() { |
||||
Map<String, Object> map = new HashMap<String, Object>(); |
||||
map.put("key", "bbs"); |
||||
try { |
||||
InputStream in = HttpKit.post("https://cloud.fanruan.com/site", map, HttpResponseType.STREAM); |
||||
String text = IOKit.inputStream2String(in, StandardCharsets.UTF_8); |
||||
assertEquals("{\"value\":\"http://bbs.fanruan.com/\"}", text); |
||||
} catch (SocketTimeoutException ignore) { |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
fail(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testStreamMock() { |
||||
server.enqueue(new MockResponse().setBody("{\"value\":\"http://bbs.fanruan.com/\"}")); |
||||
String url = server.url("/site").toString(); |
||||
Map<String, String> map = new HashMap<String, String>(); |
||||
map.put("key", "bbs"); |
||||
try { |
||||
InputStream in = HttpKit.executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(map) |
||||
.build(), |
||||
new StreamResponseHandle()); |
||||
String text = IOKit.inputStream2String(in, StandardCharsets.UTF_8); |
||||
RecordedRequest takeRequest = server.takeRequest(); |
||||
assertEquals("{\"value\":\"http://bbs.fanruan.com/\"}", text); |
||||
assertEquals("POST", takeRequest.getMethod()); |
||||
assertEquals("key=bbs", takeRequest.getBody().readUtf8()); |
||||
} catch (SocketTimeoutException ignore) { |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
fail(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testMethod() throws Exception { |
||||
server.enqueue(new MockResponse().setBody("get")); |
||||
server.enqueue(new MockResponse().setBody("post")); |
||||
server.enqueue(new MockResponse().setBody("put")); |
||||
server.enqueue(new MockResponse().setBody("delete")); |
||||
String url = server.url("/v1/chat/").toString(); |
||||
HttpKit.get(url); |
||||
assertEquals(server.takeRequest().getMethod(), "GET"); |
||||
HttpKit.post(url, Collections.<String, String>emptyMap()); |
||||
assertEquals(server.takeRequest().getMethod(), "POST"); |
||||
HttpKit.executeAndParse(HttpRequest.custom().url(url).put(Collections.<String, String>emptyMap()).build()); |
||||
assertEquals(server.takeRequest().getMethod(), "PUT"); |
||||
HttpKit.executeAndParse(HttpRequest.custom().url(url).delete().build()); |
||||
assertEquals(server.takeRequest().getMethod(), "DELETE"); |
||||
} |
||||
|
||||
@Test |
||||
public void testHeader() throws Exception { |
||||
server.enqueue(new MockResponse().setBody("hello, world!")); |
||||
HttpUrl baseUrl = server.url("/v1/chat/"); |
||||
|
||||
HashMap<String, String> headers = new HashMap<String, String>(1); |
||||
headers.put("Authorization", "abc"); |
||||
String s = HttpKit.executeAndParse(HttpRequest.custom().url(baseUrl.toString()).post(Collections.<String, String>emptyMap()).headers(headers).build()); |
||||
assertEquals("hello, world!", s); |
||||
// 测试请求头
|
||||
RecordedRequest request = server.takeRequest(); |
||||
assertEquals(request.getHeader("Authorization"), "abc"); |
||||
assertEquals("POST /v1/chat/ HTTP/1.1", request.getRequestLine()); |
||||
} |
||||
|
||||
@Test |
||||
public void testParams() throws Exception { |
||||
server.enqueue(new MockResponse().setBody("hello, world!")); |
||||
HttpUrl baseUrl = server.url("/v1/chat/"); |
||||
|
||||
HashMap<String, String> params = new HashMap<String, String>(1); |
||||
params.put("key", "value"); |
||||
String s = HttpKit.executeAndParse(HttpRequest.custom().url(baseUrl.toString()).post(params).build()); |
||||
assertEquals("hello, world!", s); |
||||
// 测试参数
|
||||
RecordedRequest request = server.takeRequest(); |
||||
assertEquals("key=value", request.getBody().readUtf8()); |
||||
assertEquals("POST /v1/chat/ HTTP/1.1", request.getRequestLine()); |
||||
} |
||||
} |
Loading…
Reference in new issue