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 响应处理器
+ * 例:
+ *
+ * String res = HttpToolbox.executeAndParse(HttpRequest
+ * .custom()
+ * .url("")
+ * .build(),
+ * TextResponseHandle.DEFAULT);
+ *
+ *
+ * @param httpRequest httpRequest
+ * @param handle http 解析器
+ * @return 返回处理结果
+ */
+ public static T executeAndParse(HttpRequest httpRequest, BaseHttpResponseHandle 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 headers = httpRequest.getHeaders();
+ if (headers != null && !headers.isEmpty()) {
+ for (Map.Entry 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 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 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 params, String paramsEncoding) throws UnsupportedEncodingException {
+ if (params == null || params.isEmpty()) {
+ return url;
+ }
+ URIBuilder builder;
+ try {
+ builder = new URIBuilder(url);
+ for (Map.Entry 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;
+ }
+}
diff --git a/src/main/java/com/fanruan/api/net/http/rs/BaseHttpResponseHandle.java b/src/main/java/com/fanruan/api/net/http/rs/BaseHttpResponseHandle.java
new file mode 100644
index 0000000..4198916
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/BaseHttpResponseHandle.java
@@ -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 {
+
+ /**
+ * 解析编码,默认为 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;
+}
diff --git a/src/main/java/com/fanruan/api/net/http/rs/HttpRequest.java b/src/main/java/com/fanruan/api/net/http/rs/HttpRequest.java
new file mode 100644
index 0000000..d29aaec
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/HttpRequest.java
@@ -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 headers;
+
+ /**
+ * 请求参数
+ */
+ private Map 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 getHeaders() {
+ return headers;
+ }
+
+ public Map 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 headers = Collections.emptyMap();
+ private Map 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 headers) {
+ if (headers != null) {
+ this.headers = headers;
+ }
+ return this;
+ }
+
+ public Builder params(Map 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 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 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;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fanruan/api/net/http/rs/HttpRequestType.java b/src/main/java/com/fanruan/api/net/http/rs/HttpRequestType.java
new file mode 100644
index 0000000..1a1ffe9
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/HttpRequestType.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/fanruan/api/net/http/rs/HttpResponseType.java b/src/main/java/com/fanruan/api/net/http/rs/HttpResponseType.java
new file mode 100644
index 0000000..a787422
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/HttpResponseType.java
@@ -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 {
+
+ /**
+ * 处理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 TEXT = new HttpResponseType() {
+
+ @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 STREAM = new HttpResponseType() {
+
+ @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();
+ }
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/main/java/com/fanruan/api/net/http/rs/StreamResponseHandle.java b/src/main/java/com/fanruan/api/net/http/rs/StreamResponseHandle.java
new file mode 100644
index 0000000..e10bfdd
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/StreamResponseHandle.java
@@ -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 {
+
+ 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();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/fanruan/api/net/http/rs/TextResponseHandle.java b/src/main/java/com/fanruan/api/net/http/rs/TextResponseHandle.java
new file mode 100644
index 0000000..c8c58c0
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/TextResponseHandle.java
@@ -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 {
+
+ 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();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/fanruan/api/net/http/rs/UploadResponseHandle.java b/src/main/java/com/fanruan/api/net/http/rs/UploadResponseHandle.java
new file mode 100644
index 0000000..3b68be0
--- /dev/null
+++ b/src/main/java/com/fanruan/api/net/http/rs/UploadResponseHandle.java
@@ -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 {
+
+ 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;
+ }
+}
diff --git a/src/test/java/com/fanruan/api/net/http/HttpKitTest.java b/src/test/java/com/fanruan/api/net/http/HttpKitTest.java
new file mode 100644
index 0000000..a034a4a
--- /dev/null
+++ b/src/test/java/com/fanruan/api/net/http/HttpKitTest.java
@@ -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 map = new HashMap();
+ 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 map = new HashMap();
+ 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 map = new HashMap();
+ 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.emptyMap());
+ assertEquals(server.takeRequest().getMethod(), "POST");
+ HttpKit.executeAndParse(HttpRequest.custom().url(url).put(Collections.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 headers = new HashMap(1);
+ headers.put("Authorization", "abc");
+ String s = HttpKit.executeAndParse(HttpRequest.custom().url(baseUrl.toString()).post(Collections.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 params = new HashMap(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());
+ }
+}
\ No newline at end of file