mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-04 12:47:59 +08:00
add HttpConfig
This commit is contained in:
parent
6a79844dec
commit
c3cdbf5bb5
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
### ❌不兼容特性
|
### ❌不兼容特性
|
||||||
* 【extra 】 【可能兼容问题】BeanCopierCache的key结构变更
|
* 【extra 】 【可能兼容问题】BeanCopierCache的key结构变更
|
||||||
|
* 【http 】 【可能兼容问题】HttpInterceptor增加泛型标识,HttpRequest中配置汇总于HttpConfig
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【core 】 MapUtil增加entry、ofEntries方法
|
* 【core 】 MapUtil增加entry、ofEntries方法
|
||||||
@ -13,6 +14,7 @@
|
|||||||
* 【core 】 IterUtil增加filtered,增加FilterIter(issue#2228)
|
* 【core 】 IterUtil增加filtered,增加FilterIter(issue#2228)
|
||||||
* 【core 】 增加NodeListIter、ResettableIter
|
* 【core 】 增加NodeListIter、ResettableIter
|
||||||
* 【crypto 】 HmacAlgorithm增加SM4CMAC(issue#2206@Github)
|
* 【crypto 】 HmacAlgorithm增加SM4CMAC(issue#2206@Github)
|
||||||
|
* 【http 】 增加HttpConfig,响应支持拦截(issue#2217@Github)
|
||||||
|
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【core 】 IdcardUtil#getCityCodeByIdCard位数问题(issue#2224@Github)
|
* 【core 】 IdcardUtil#getCityCodeByIdCard位数问题(issue#2224@Github)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package cn.hutool.http;
|
package cn.hutool.http;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局的拦截器
|
* 全局的拦截器<br>
|
||||||
|
* 包括请求拦截器和响应拦截器
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
@ -9,34 +10,81 @@ package cn.hutool.http;
|
|||||||
public enum GlobalInterceptor {
|
public enum GlobalInterceptor {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
private final HttpInterceptor.Chain interceptors = new HttpInterceptor.Chain();
|
private final HttpInterceptor.Chain<HttpRequest> requestInterceptors = new HttpInterceptor.Chain<>();
|
||||||
|
private final HttpInterceptor.Chain<HttpResponse> responseInterceptors = new HttpInterceptor.Chain<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置拦截器,用于在请求前重新编辑请求
|
* 设置拦截器,用于在请求前重新编辑请求
|
||||||
*
|
*
|
||||||
* @param interceptor 拦截器实现
|
* @param interceptor 拦截器实现
|
||||||
*/
|
*/
|
||||||
synchronized public GlobalInterceptor addInterceptor(HttpInterceptor interceptor) {
|
synchronized public GlobalInterceptor addRequestInterceptor(HttpInterceptor<HttpRequest> interceptor) {
|
||||||
this.interceptors.addChain(interceptor);
|
this.requestInterceptors.addChain(interceptor);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空
|
* 设置拦截器,用于在响应读取后完成编辑或读取
|
||||||
|
*
|
||||||
|
* @param interceptor 拦截器实现
|
||||||
|
*/
|
||||||
|
synchronized public GlobalInterceptor addResponseInterceptor(HttpInterceptor<HttpResponse> interceptor) {
|
||||||
|
this.responseInterceptors.addChain(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空请求和响应拦截器
|
||||||
|
*
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
synchronized public GlobalInterceptor clear(){
|
public GlobalInterceptor clear() {
|
||||||
interceptors.clear();
|
clearRequest();
|
||||||
|
clearResponse();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制过滤器列表
|
* 清空请求拦截器
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
synchronized public GlobalInterceptor clearRequest() {
|
||||||
|
requestInterceptors.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空响应拦截器
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
synchronized public GlobalInterceptor clearResponse() {
|
||||||
|
responseInterceptors.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制请求过滤器列表
|
||||||
|
*
|
||||||
* @return {@link cn.hutool.http.HttpInterceptor.Chain}
|
* @return {@link cn.hutool.http.HttpInterceptor.Chain}
|
||||||
*/
|
*/
|
||||||
HttpInterceptor.Chain getCopied(){
|
HttpInterceptor.Chain<HttpRequest> getCopiedRequestInterceptor() {
|
||||||
final HttpInterceptor.Chain copied = new HttpInterceptor.Chain();
|
final HttpInterceptor.Chain<HttpRequest> copied = new HttpInterceptor.Chain<>();
|
||||||
for (HttpInterceptor interceptor : this.interceptors) {
|
for (HttpInterceptor<HttpRequest> interceptor : this.requestInterceptors) {
|
||||||
|
copied.addChain(interceptor);
|
||||||
|
}
|
||||||
|
return copied;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制响应过滤器列表
|
||||||
|
*
|
||||||
|
* @return {@link cn.hutool.http.HttpInterceptor.Chain}
|
||||||
|
*/
|
||||||
|
HttpInterceptor.Chain<HttpResponse> getCopiedResponseInterceptor() {
|
||||||
|
final HttpInterceptor.Chain<HttpResponse> copied = new HttpInterceptor.Chain<>();
|
||||||
|
for (HttpInterceptor<HttpResponse> interceptor : this.responseInterceptors) {
|
||||||
copied.addChain(interceptor);
|
copied.addChain(interceptor);
|
||||||
}
|
}
|
||||||
return copied;
|
return copied;
|
||||||
|
296
hutool-http/src/main/java/cn/hutool/http/HttpConfig.java
Executable file
296
hutool-http/src/main/java/cn/hutool/http/HttpConfig.java
Executable file
@ -0,0 +1,296 @@
|
|||||||
|
package cn.hutool.http;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.net.SSLUtil;
|
||||||
|
|
||||||
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http配置项
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.8.0
|
||||||
|
*/
|
||||||
|
public class HttpConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认Http配置信息
|
||||||
|
*
|
||||||
|
* @return HttpConfig
|
||||||
|
*/
|
||||||
|
public static HttpConfig create() {
|
||||||
|
return new HttpConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认连接超时
|
||||||
|
*/
|
||||||
|
int connectionTimeout = HttpGlobalConfig.getTimeout();
|
||||||
|
/**
|
||||||
|
* 默认读取超时
|
||||||
|
*/
|
||||||
|
int readTimeout = HttpGlobalConfig.getTimeout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否禁用缓存
|
||||||
|
*/
|
||||||
|
boolean isDisableCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大重定向次数
|
||||||
|
*/
|
||||||
|
int maxRedirectCount = HttpGlobalConfig.getMaxRedirectCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理
|
||||||
|
*/
|
||||||
|
Proxy proxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HostnameVerifier,用于HTTPS安全连接
|
||||||
|
*/
|
||||||
|
HostnameVerifier hostnameVerifier;
|
||||||
|
/**
|
||||||
|
* SSLSocketFactory,用于HTTPS安全连接
|
||||||
|
*/
|
||||||
|
SSLSocketFactory ssf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chuncked块大小,0或小于0表示不设置Chuncked模式
|
||||||
|
*/
|
||||||
|
int blockSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取是否忽略响应读取时可能的EOF异常。<br>
|
||||||
|
* 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。<br>
|
||||||
|
* 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。
|
||||||
|
*/
|
||||||
|
boolean ignoreEOFError = HttpGlobalConfig.isIgnoreEOFError();
|
||||||
|
/**
|
||||||
|
* 获取是否忽略解码URL,包括URL中的Path部分和Param部分。<br>
|
||||||
|
* 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,<br>
|
||||||
|
* 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。
|
||||||
|
*/
|
||||||
|
boolean decodeUrl = HttpGlobalConfig.isDecodeUrl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求前的拦截器,用于在请求前重新编辑请求
|
||||||
|
*/
|
||||||
|
final HttpInterceptor.Chain<HttpRequest> requestInterceptors = GlobalInterceptor.INSTANCE.getCopiedRequestInterceptor();
|
||||||
|
/**
|
||||||
|
* 响应后的拦截器,用于在响应后处理逻辑
|
||||||
|
*/
|
||||||
|
final HttpInterceptor.Chain<HttpResponse> responseInterceptors = GlobalInterceptor.INSTANCE.getCopiedResponseInterceptor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向时是否使用拦截器
|
||||||
|
*/
|
||||||
|
boolean interceptorOnRedirect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置超时,单位:毫秒<br>
|
||||||
|
* 超时包括:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1. 连接超时
|
||||||
|
* 2. 读取响应超时
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param milliseconds 超时毫秒数
|
||||||
|
* @return this
|
||||||
|
* @see #setConnectionTimeout(int)
|
||||||
|
* @see #setReadTimeout(int)
|
||||||
|
*/
|
||||||
|
public HttpConfig timeout(int milliseconds) {
|
||||||
|
setConnectionTimeout(milliseconds);
|
||||||
|
setReadTimeout(milliseconds);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置连接超时,单位:毫秒
|
||||||
|
*
|
||||||
|
* @param milliseconds 超时毫秒数
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setConnectionTimeout(int milliseconds) {
|
||||||
|
this.connectionTimeout = milliseconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置连接超时,单位:毫秒
|
||||||
|
*
|
||||||
|
* @param milliseconds 超时毫秒数
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setReadTimeout(int milliseconds) {
|
||||||
|
this.readTimeout = milliseconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用缓存
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig disableCache() {
|
||||||
|
this.isDisableCache = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置最大重定向次数<br>
|
||||||
|
* 如果次数小于1则表示不重定向,大于等于1表示打开重定向
|
||||||
|
*
|
||||||
|
* @param maxRedirectCount 最大重定向次数
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setMaxRedirectCount(int maxRedirectCount) {
|
||||||
|
this.maxRedirectCount = Math.max(maxRedirectCount, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置域名验证器<br>
|
||||||
|
* 只针对HTTPS请求,如果不设置,不做验证,所有域名被信任
|
||||||
|
*
|
||||||
|
* @param hostnameVerifier HostnameVerifier
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setHostnameVerifier(HostnameVerifier hostnameVerifier) {
|
||||||
|
// 验证域
|
||||||
|
this.hostnameVerifier = hostnameVerifier;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置Http代理
|
||||||
|
*
|
||||||
|
* @param host 代理 主机
|
||||||
|
* @param port 代理 端口
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setHttpProxy(String host, int port) {
|
||||||
|
final Proxy proxy = new Proxy(Proxy.Type.HTTP,
|
||||||
|
new InetSocketAddress(host, port));
|
||||||
|
return setProxy(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置代理
|
||||||
|
*
|
||||||
|
* @param proxy 代理 {@link Proxy}
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setProxy(Proxy proxy) {
|
||||||
|
this.proxy = proxy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置SSLSocketFactory<br>
|
||||||
|
* 只针对HTTPS请求,如果不设置,使用默认的SSLSocketFactory<br>
|
||||||
|
* 默认SSLSocketFactory为:SSLSocketFactoryBuilder.create().build();
|
||||||
|
*
|
||||||
|
* @param ssf SSLScketFactory
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setSSLSocketFactory(SSLSocketFactory ssf) {
|
||||||
|
this.ssf = ssf;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置HTTPS安全连接协议,只针对HTTPS请求,可以使用的协议包括:<br>
|
||||||
|
* 此方法调用后{@link #setSSLSocketFactory(SSLSocketFactory)} 将被覆盖。
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1. TLSv1.2
|
||||||
|
* 2. TLSv1.1
|
||||||
|
* 3. SSLv3
|
||||||
|
* ...
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param protocol 协议
|
||||||
|
* @return this
|
||||||
|
* @see SSLUtil#createSSLContext(String)
|
||||||
|
* @see #setSSLSocketFactory(SSLSocketFactory)
|
||||||
|
*/
|
||||||
|
public HttpConfig setSSLProtocol(String protocol) {
|
||||||
|
Assert.notBlank(protocol, "protocol must be not blank!");
|
||||||
|
setSSLSocketFactory(SSLUtil.createSSLContext(protocol).getSocketFactory());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 采用流方式上传数据,无需本地缓存数据。<br>
|
||||||
|
* HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。
|
||||||
|
*
|
||||||
|
* @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setBlockSize(int blockSize) {
|
||||||
|
this.blockSize = blockSize;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否忽略响应读取时可能的EOF异常。<br>
|
||||||
|
* 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。<br>
|
||||||
|
* 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。
|
||||||
|
*
|
||||||
|
* @param ignoreEOFError 是否忽略响应读取时可能的EOF异常。
|
||||||
|
* @since 5.7.20
|
||||||
|
*/
|
||||||
|
public HttpConfig setIgnoreEOFError(boolean ignoreEOFError) {
|
||||||
|
this.ignoreEOFError = ignoreEOFError;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否忽略解码URL,包括URL中的Path部分和Param部分。<br>
|
||||||
|
* 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,<br>
|
||||||
|
* 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。
|
||||||
|
*
|
||||||
|
* @param decodeUrl 是否忽略解码URL
|
||||||
|
*/
|
||||||
|
public HttpConfig setDecodeUrl(boolean decodeUrl) {
|
||||||
|
this.decodeUrl = decodeUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置拦截器,用于在请求前重新编辑请求
|
||||||
|
*
|
||||||
|
* @param interceptor 拦截器实现
|
||||||
|
*/
|
||||||
|
public HttpConfig addRequestInterceptor(HttpInterceptor<HttpRequest> interceptor) {
|
||||||
|
this.requestInterceptors.addChain(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置拦截器,用于在请求前重新编辑请求
|
||||||
|
*
|
||||||
|
* @param interceptor 拦截器实现
|
||||||
|
*/
|
||||||
|
public HttpConfig addResponseInterceptor(HttpInterceptor<HttpResponse> interceptor) {
|
||||||
|
this.responseInterceptors.addChain(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向时是否使用拦截器
|
||||||
|
*
|
||||||
|
* @param interceptorOnRedirect 重定向时是否使用拦截器
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConfig setInterceptorOnRedirect(boolean interceptorOnRedirect) {
|
||||||
|
this.interceptorOnRedirect = interceptorOnRedirect;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -5,38 +5,40 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Http拦截器接口,通过实现此接口,完成请求发起前对请求的编辑工作
|
* Http拦截器接口,通过实现此接口,完成请求发起前或结束后对请求的编辑工作
|
||||||
*
|
*
|
||||||
|
* @param <T> 过滤参数类型,HttpRequest或者HttpResponse
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 5.7.16
|
* @since 5.7.16
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface HttpInterceptor {
|
public interface HttpInterceptor<T extends HttpBase<T>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理请求
|
* 处理请求
|
||||||
*
|
*
|
||||||
* @param request 请求
|
* @param httpObj 请求或响应对象
|
||||||
*/
|
*/
|
||||||
void process(HttpRequest request);
|
void process(T httpObj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截器链
|
* 拦截器链
|
||||||
*
|
*
|
||||||
|
* @param <T> 过滤参数类型,HttpRequest或者HttpResponse
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 5.7.16
|
* @since 5.7.16
|
||||||
*/
|
*/
|
||||||
class Chain implements cn.hutool.core.lang.Chain<HttpInterceptor, Chain> {
|
class Chain<T extends HttpBase<T>> implements cn.hutool.core.lang.Chain<HttpInterceptor<T>, Chain<T>> {
|
||||||
private final List<HttpInterceptor> interceptors = new LinkedList<>();
|
private final List<HttpInterceptor<T>> interceptors = new LinkedList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Chain addChain(HttpInterceptor element) {
|
public Chain<T> addChain(HttpInterceptor<T> element) {
|
||||||
interceptors.add(element);
|
interceptors.add(element);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<HttpInterceptor> iterator() {
|
public Iterator<HttpInterceptor<T>> iterator() {
|
||||||
return interceptors.iterator();
|
return interceptors.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ public interface HttpInterceptor {
|
|||||||
* @return this
|
* @return this
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public Chain clear() {
|
public Chain<T> clear() {
|
||||||
interceptors.clear();
|
interceptors.clear();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import java.io.IOException;
|
|||||||
import java.net.CookieManager;
|
import java.net.CookieManager;
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.URLStreamHandler;
|
import java.net.URLStreamHandler;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
@ -200,43 +199,27 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
}
|
}
|
||||||
// ---------------------------------------------------------------- static Http Method end
|
// ---------------------------------------------------------------- static Http Method end
|
||||||
|
|
||||||
|
private HttpConfig config = HttpConfig.create();
|
||||||
private UrlBuilder url;
|
private UrlBuilder url;
|
||||||
private URLStreamHandler urlHandler;
|
private URLStreamHandler urlHandler;
|
||||||
private Method method = Method.GET;
|
private Method method = Method.GET;
|
||||||
/**
|
/**
|
||||||
* 请求前的拦截器,用于在请求前重新编辑请求
|
* 连接对象
|
||||||
*/
|
*/
|
||||||
private final HttpInterceptor.Chain interceptors = GlobalInterceptor.INSTANCE.getCopied();
|
private HttpConnection httpConnection;
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认连接超时
|
|
||||||
*/
|
|
||||||
private int connectionTimeout = HttpGlobalConfig.getTimeout();
|
|
||||||
/**
|
|
||||||
* 默认读取超时
|
|
||||||
*/
|
|
||||||
private int readTimeout = HttpGlobalConfig.getTimeout();
|
|
||||||
/**
|
/**
|
||||||
* 存储表单数据
|
* 存储表单数据
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> form;
|
private Map<String, Object> form;
|
||||||
/**
|
|
||||||
* 是否为Multipart表单
|
|
||||||
*/
|
|
||||||
private boolean isMultiPart;
|
|
||||||
/**
|
/**
|
||||||
* Cookie
|
* Cookie
|
||||||
*/
|
*/
|
||||||
private String cookie;
|
private String cookie;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接对象
|
* 是否为Multipart表单
|
||||||
*/
|
*/
|
||||||
private HttpConnection httpConnection;
|
private boolean isMultiPart;
|
||||||
/**
|
|
||||||
* 是否禁用缓存
|
|
||||||
*/
|
|
||||||
private boolean isDisableCache;
|
|
||||||
/**
|
/**
|
||||||
* 是否是REST请求模式
|
* 是否是REST请求模式
|
||||||
*/
|
*/
|
||||||
@ -245,27 +228,6 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* 重定向次数计数器,内部使用
|
* 重定向次数计数器,内部使用
|
||||||
*/
|
*/
|
||||||
private int redirectCount;
|
private int redirectCount;
|
||||||
/**
|
|
||||||
* 最大重定向次数
|
|
||||||
*/
|
|
||||||
private int maxRedirectCount = HttpGlobalConfig.getMaxRedirectCount();
|
|
||||||
/**
|
|
||||||
* Chuncked块大小,0或小于0表示不设置Chuncked模式
|
|
||||||
*/
|
|
||||||
private int blockSize;
|
|
||||||
/**
|
|
||||||
* 代理
|
|
||||||
*/
|
|
||||||
private Proxy proxy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HostnameVerifier,用于HTTPS安全连接
|
|
||||||
*/
|
|
||||||
private HostnameVerifier hostnameVerifier;
|
|
||||||
/**
|
|
||||||
* SSLSocketFactory,用于HTTPS安全连接
|
|
||||||
*/
|
|
||||||
private SSLSocketFactory ssf;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造,URL编码默认使用UTF-8
|
* 构造,URL编码默认使用UTF-8
|
||||||
@ -784,6 +746,18 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
}
|
}
|
||||||
// ---------------------------------------------------------------- Body end
|
// ---------------------------------------------------------------- Body end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将新的配置加入<br>
|
||||||
|
* 注意加入的配置可能被修改
|
||||||
|
*
|
||||||
|
* @param config 配置
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpRequest setConfig(HttpConfig config){
|
||||||
|
this.config = config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置超时,单位:毫秒<br>
|
* 设置超时,单位:毫秒<br>
|
||||||
* 超时包括:
|
* 超时包括:
|
||||||
@ -799,8 +773,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @see #setReadTimeout(int)
|
* @see #setReadTimeout(int)
|
||||||
*/
|
*/
|
||||||
public HttpRequest timeout(int milliseconds) {
|
public HttpRequest timeout(int milliseconds) {
|
||||||
setConnectionTimeout(milliseconds);
|
config.timeout(milliseconds);
|
||||||
setReadTimeout(milliseconds);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +785,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 4.5.6
|
* @since 4.5.6
|
||||||
*/
|
*/
|
||||||
public HttpRequest setConnectionTimeout(int milliseconds) {
|
public HttpRequest setConnectionTimeout(int milliseconds) {
|
||||||
this.connectionTimeout = milliseconds;
|
config.setConnectionTimeout(milliseconds);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,7 +797,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 4.5.6
|
* @since 4.5.6
|
||||||
*/
|
*/
|
||||||
public HttpRequest setReadTimeout(int milliseconds) {
|
public HttpRequest setReadTimeout(int milliseconds) {
|
||||||
this.readTimeout = milliseconds;
|
config.setReadTimeout(milliseconds);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,7 +807,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public HttpRequest disableCache() {
|
public HttpRequest disableCache() {
|
||||||
this.isDisableCache = true;
|
config.disableCache();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,7 +831,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 3.3.0
|
* @since 3.3.0
|
||||||
*/
|
*/
|
||||||
public HttpRequest setMaxRedirectCount(int maxRedirectCount) {
|
public HttpRequest setMaxRedirectCount(int maxRedirectCount) {
|
||||||
this.maxRedirectCount = Math.max(maxRedirectCount, 0);
|
config.setMaxRedirectCount(maxRedirectCount);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,8 +843,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public HttpRequest setHostnameVerifier(HostnameVerifier hostnameVerifier) {
|
public HttpRequest setHostnameVerifier(HostnameVerifier hostnameVerifier) {
|
||||||
// 验证域
|
config.setHostnameVerifier(hostnameVerifier);
|
||||||
this.hostnameVerifier = hostnameVerifier;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,9 +856,8 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 5.4.5
|
* @since 5.4.5
|
||||||
*/
|
*/
|
||||||
public HttpRequest setHttpProxy(String host, int port) {
|
public HttpRequest setHttpProxy(String host, int port) {
|
||||||
final Proxy proxy = new Proxy(Proxy.Type.HTTP,
|
config.setHttpProxy(host, port);
|
||||||
new InetSocketAddress(host, port));
|
return this;
|
||||||
return setProxy(proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -896,7 +867,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public HttpRequest setProxy(Proxy proxy) {
|
public HttpRequest setProxy(Proxy proxy) {
|
||||||
this.proxy = proxy;
|
config.setProxy(proxy);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,7 +880,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public HttpRequest setSSLSocketFactory(SSLSocketFactory ssf) {
|
public HttpRequest setSSLSocketFactory(SSLSocketFactory ssf) {
|
||||||
this.ssf = ssf;
|
config.setSSLSocketFactory(ssf);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,8 +901,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @see #setSSLSocketFactory(SSLSocketFactory)
|
* @see #setSSLSocketFactory(SSLSocketFactory)
|
||||||
*/
|
*/
|
||||||
public HttpRequest setSSLProtocol(String protocol) {
|
public HttpRequest setSSLProtocol(String protocol) {
|
||||||
Assert.notBlank(protocol, "protocol must be not blank!");
|
config.setSSLProtocol(protocol);
|
||||||
setSSLSocketFactory(SSLUtil.createSSLContext(protocol).getSocketFactory());
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +927,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 4.6.5
|
* @since 4.6.5
|
||||||
*/
|
*/
|
||||||
public HttpRequest setChunkedStreamingMode(int blockSize) {
|
public HttpRequest setChunkedStreamingMode(int blockSize) {
|
||||||
this.blockSize = blockSize;
|
config.setBlockSize(blockSize);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,9 +936,31 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
*
|
*
|
||||||
* @param interceptor 拦截器实现
|
* @param interceptor 拦截器实现
|
||||||
* @since 5.7.16
|
* @since 5.7.16
|
||||||
|
* @see #addRequestInterceptor(HttpInterceptor)
|
||||||
*/
|
*/
|
||||||
public HttpRequest addInterceptor(HttpInterceptor interceptor) {
|
public HttpRequest addInterceptor(HttpInterceptor<HttpRequest> interceptor) {
|
||||||
this.interceptors.addChain(interceptor);
|
return addRequestInterceptor(interceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置拦截器,用于在请求前重新编辑请求
|
||||||
|
*
|
||||||
|
* @param interceptor 拦截器实现
|
||||||
|
* @since 5.8.0
|
||||||
|
*/
|
||||||
|
public HttpRequest addRequestInterceptor(HttpInterceptor<HttpRequest> interceptor) {
|
||||||
|
config.addRequestInterceptor(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置拦截器,用于在请求前重新编辑请求
|
||||||
|
*
|
||||||
|
* @param interceptor 拦截器实现
|
||||||
|
* @since 5.8.0
|
||||||
|
*/
|
||||||
|
public HttpRequest addResponseInterceptor(HttpInterceptor<HttpResponse> interceptor) {
|
||||||
|
config.addResponseInterceptor(interceptor);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1002,7 +994,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public HttpResponse execute(boolean isAsync) {
|
public HttpResponse execute(boolean isAsync) {
|
||||||
return doExecute(isAsync, this.interceptors);
|
return doExecute(isAsync, config.requestInterceptors, config.responseInterceptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1096,12 +1088,14 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* 执行Reuqest请求
|
* 执行Reuqest请求
|
||||||
*
|
*
|
||||||
* @param isAsync 是否异步
|
* @param isAsync 是否异步
|
||||||
* @param interceptors 拦截器列表
|
* @param requestInterceptors 请求拦截器列表
|
||||||
|
* @param responseInterceptors 响应拦截器列表
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private HttpResponse doExecute(boolean isAsync, HttpInterceptor.Chain interceptors) {
|
private HttpResponse doExecute(boolean isAsync, HttpInterceptor.Chain<HttpRequest> requestInterceptors,
|
||||||
if (null != interceptors) {
|
HttpInterceptor.Chain<HttpResponse> responseInterceptors) {
|
||||||
for (HttpInterceptor interceptor : interceptors) {
|
if (null != requestInterceptors) {
|
||||||
|
for (HttpInterceptor<HttpRequest> interceptor : requestInterceptors) {
|
||||||
interceptor.process(this);
|
interceptor.process(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1118,7 +1112,14 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
|
|
||||||
// 获取响应
|
// 获取响应
|
||||||
if (null == httpResponse) {
|
if (null == httpResponse) {
|
||||||
httpResponse = new HttpResponse(this.httpConnection, this.charset, isAsync, isIgnoreResponseBody());
|
httpResponse = new HttpResponse(this.httpConnection, this.config, this.charset, isAsync, isIgnoreResponseBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拦截响应
|
||||||
|
if (null != responseInterceptors) {
|
||||||
|
for (HttpInterceptor<HttpResponse> interceptor : responseInterceptors) {
|
||||||
|
interceptor.process(httpResponse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return httpResponse;
|
return httpResponse;
|
||||||
@ -1134,15 +1135,15 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.httpConnection = HttpConnection
|
this.httpConnection = HttpConnection
|
||||||
.create(this.url.toURL(this.urlHandler), this.proxy)//
|
.create(this.url.toURL(this.urlHandler), config.proxy)//
|
||||||
.setConnectTimeout(this.connectionTimeout)//
|
.setConnectTimeout(config.connectionTimeout)//
|
||||||
.setReadTimeout(this.readTimeout)//
|
.setReadTimeout(config.readTimeout)//
|
||||||
.setMethod(this.method)//
|
.setMethod(this.method)//
|
||||||
.setHttpsInfo(this.hostnameVerifier, this.ssf)//
|
.setHttpsInfo(config.hostnameVerifier, config.ssf)//
|
||||||
// 关闭JDK自动转发,采用手动转发方式
|
// 关闭JDK自动转发,采用手动转发方式
|
||||||
.setInstanceFollowRedirects(false)
|
.setInstanceFollowRedirects(false)
|
||||||
// 流方式上传数据
|
// 流方式上传数据
|
||||||
.setChunkedStreamingMode(this.blockSize)
|
.setChunkedStreamingMode(config.blockSize)
|
||||||
// 覆盖默认Header
|
// 覆盖默认Header
|
||||||
.header(this.headers, true);
|
.header(this.headers, true);
|
||||||
|
|
||||||
@ -1155,7 +1156,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否禁用缓存
|
// 是否禁用缓存
|
||||||
if (this.isDisableCache) {
|
if (config.isDisableCache) {
|
||||||
this.httpConnection.disableCache();
|
this.httpConnection.disableCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1184,7 +1185,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
*/
|
*/
|
||||||
private HttpResponse sendRedirectIfPossible(boolean isAsync) {
|
private HttpResponse sendRedirectIfPossible(boolean isAsync) {
|
||||||
// 手动实现重定向
|
// 手动实现重定向
|
||||||
if (this.maxRedirectCount > 0) {
|
if (config.maxRedirectCount > 0) {
|
||||||
int responseCode;
|
int responseCode;
|
||||||
try {
|
try {
|
||||||
responseCode = httpConnection.responseCode();
|
responseCode = httpConnection.responseCode();
|
||||||
@ -1197,10 +1198,11 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||||
if (HttpStatus.isRedirected(responseCode)) {
|
if (HttpStatus.isRedirected(responseCode)) {
|
||||||
setUrl(UrlBuilder.ofHttpWithoutEncode(httpConnection.header(Header.LOCATION)));
|
setUrl(UrlBuilder.ofHttpWithoutEncode(httpConnection.header(Header.LOCATION)));
|
||||||
if (redirectCount < this.maxRedirectCount) {
|
if (redirectCount < config.maxRedirectCount) {
|
||||||
redirectCount++;
|
redirectCount++;
|
||||||
// 重定向不再走过滤器
|
// 重定向不再走过滤器
|
||||||
return doExecute(isAsync, null);
|
return doExecute(isAsync, config.interceptorOnRedirect ? config.requestInterceptors : null,
|
||||||
|
config.interceptorOnRedirect ? config.responseInterceptors : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ import java.util.Map.Entry;
|
|||||||
*/
|
*/
|
||||||
public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http配置
|
||||||
|
*/
|
||||||
|
protected HttpConfig config;
|
||||||
/**
|
/**
|
||||||
* 持有连接对象
|
* 持有连接对象
|
||||||
*/
|
*/
|
||||||
@ -62,13 +66,15 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param httpConnection {@link HttpConnection}
|
* @param httpConnection {@link HttpConnection}
|
||||||
|
* @param config Http配置
|
||||||
* @param charset 编码,从请求编码中获取默认编码
|
* @param charset 编码,从请求编码中获取默认编码
|
||||||
* @param isAsync 是否异步
|
* @param isAsync 是否异步
|
||||||
* @param isIgnoreBody 是否忽略读取响应体
|
* @param isIgnoreBody 是否忽略读取响应体
|
||||||
* @since 3.1.2
|
* @since 3.1.2
|
||||||
*/
|
*/
|
||||||
protected HttpResponse(HttpConnection httpConnection, Charset charset, boolean isAsync, boolean isIgnoreBody) {
|
protected HttpResponse(HttpConnection httpConnection, HttpConfig config, Charset charset, boolean isAsync, boolean isIgnoreBody) {
|
||||||
this.httpConnection = httpConnection;
|
this.httpConnection = httpConnection;
|
||||||
|
this.config = config;
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
this.isAsync = isAsync;
|
this.isAsync = isAsync;
|
||||||
this.ignoreBody = isIgnoreBody;
|
this.ignoreBody = isIgnoreBody;
|
||||||
@ -273,7 +279,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
Assert.notNull(out, "[out] must be not null!");
|
Assert.notNull(out, "[out] must be not null!");
|
||||||
final long contentLength = contentLength();
|
final long contentLength = contentLength();
|
||||||
try {
|
try {
|
||||||
return copyBody(bodyStream(), out, contentLength, streamProgress);
|
return copyBody(bodyStream(), out, contentLength, streamProgress, this.config.ignoreEOFError);
|
||||||
} finally {
|
} finally {
|
||||||
IoUtil.close(this);
|
IoUtil.close(this);
|
||||||
if (isCloseOut) {
|
if (isCloseOut) {
|
||||||
@ -563,7 +569,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
|
|
||||||
final long contentLength = contentLength();
|
final long contentLength = contentLength();
|
||||||
final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength);
|
final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength);
|
||||||
copyBody(in, out, contentLength, null);
|
copyBody(in, out, contentLength, null, this.config.ignoreEOFError);
|
||||||
this.bodyBytes = out.toByteArray();
|
this.bodyBytes = out.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,9 +582,10 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
* @param out 写出的流
|
* @param out 写出的流
|
||||||
* @param contentLength 总长度,-1表示未知
|
* @param contentLength 总长度,-1表示未知
|
||||||
* @param streamProgress 进度显示接口,通过实现此接口显示下载进度
|
* @param streamProgress 进度显示接口,通过实现此接口显示下载进度
|
||||||
|
* @param isIgnoreEOFError 是否忽略响应读取时可能的EOF异常
|
||||||
* @return 拷贝长度
|
* @return 拷贝长度
|
||||||
*/
|
*/
|
||||||
private static long copyBody(InputStream in, OutputStream out, long contentLength, StreamProgress streamProgress) {
|
private static long copyBody(InputStream in, OutputStream out, long contentLength, StreamProgress streamProgress, boolean isIgnoreEOFError) {
|
||||||
if (null == out) {
|
if (null == out) {
|
||||||
throw new NullPointerException("[out] is null!");
|
throw new NullPointerException("[out] is null!");
|
||||||
}
|
}
|
||||||
@ -588,7 +595,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
copyLength = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE, contentLength, streamProgress);
|
copyLength = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE, contentLength, streamProgress);
|
||||||
} catch (IORuntimeException e) {
|
} catch (IORuntimeException e) {
|
||||||
//noinspection StatementWithEmptyBody
|
//noinspection StatementWithEmptyBody
|
||||||
if (HttpGlobalConfig.isIgnoreEOFError()
|
if (isIgnoreEOFError
|
||||||
&& (e.getCause() instanceof EOFException || StrUtil.containsIgnoreCase(e.getMessage(), "Premature EOF"))) {
|
&& (e.getCause() instanceof EOFException || StrUtil.containsIgnoreCase(e.getMessage(), "Premature EOF"))) {
|
||||||
// 忽略读取HTTP流中的EOF错误
|
// 忽略读取HTTP流中的EOF错误
|
||||||
} else {
|
} else {
|
||||||
|
@ -171,13 +171,16 @@ public class HttpRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void addInterceptorTest() {
|
public void addInterceptorTest() {
|
||||||
HttpUtil.createGet("https://hutool.cn").addInterceptor(Console::log).execute();
|
HttpUtil.createGet("https://hutool.cn")
|
||||||
|
.addInterceptor(Console::log)
|
||||||
|
.addResponseInterceptor((res)-> Console.log(res.getStatus()))
|
||||||
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void addGlobalInterceptorTest() {
|
public void addGlobalInterceptorTest() {
|
||||||
GlobalInterceptor.INSTANCE.addInterceptor(Console::log);
|
GlobalInterceptor.INSTANCE.addRequestInterceptor(Console::log);
|
||||||
HttpUtil.createGet("https://hutool.cn").execute();
|
HttpUtil.createGet("https://hutool.cn").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user