mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add patch support
This commit is contained in:
parent
1ed2ec9dc4
commit
405a92cfe4
@ -10,6 +10,7 @@
|
||||
* 【core 】 增加ReflectUtil.getFieldValue支持Alias注解
|
||||
* 【core 】 Bean字段支持Alias注解(包括转map,转bean等)
|
||||
* 【core 】 增加ValueListHandler,优化结果集获取方式
|
||||
* 【http 】 支持patch方法(issue#666@Github)
|
||||
|
||||
### Bug修复
|
||||
|
||||
|
@ -1849,7 +1849,9 @@ public class DateUtil {
|
||||
* @param checkDate 检查时间,可以是当前时间,既
|
||||
* @return 是否过期
|
||||
* @since 5.1.1
|
||||
* @deprecated 使用isIn方法
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isExpired(Date startDate, Date endDate, Date checkDate) {
|
||||
return betweenMs(startDate, checkDate) > betweenMs(startDate, endDate);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ public class ReflectUtil {
|
||||
/**
|
||||
* 设置字段值
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param obj 对象,static字段则此处传Class
|
||||
* @param fieldName 字段名
|
||||
* @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
|
||||
* @throws UtilException 包装IllegalAccessException异常
|
||||
@ -303,7 +303,7 @@ public class ReflectUtil {
|
||||
Assert.notNull(obj);
|
||||
Assert.notBlank(fieldName);
|
||||
|
||||
final Field field = getField(obj.getClass(), fieldName);
|
||||
final Field field = getField((obj instanceof Class) ? (Class<?>)obj : obj.getClass(), fieldName);
|
||||
Assert.notNull(field, "Field [{}] is not exist in [{}]", fieldName, obj.getClass().getName());
|
||||
setFieldValue(obj, field, value);
|
||||
}
|
||||
@ -317,9 +317,7 @@ public class ReflectUtil {
|
||||
* @throws UtilException UtilException 包装IllegalAccessException异常
|
||||
*/
|
||||
public static void setFieldValue(Object obj, Field field, Object value) throws UtilException {
|
||||
Assert.notNull(field, "Field in [{}] not exist !", obj.getClass().getName());
|
||||
|
||||
setAccessible(field);
|
||||
Assert.notNull(field, "Field in [{}] not exist !", obj);
|
||||
|
||||
if (null != value) {
|
||||
Class<?> fieldType = field.getType();
|
||||
@ -332,10 +330,11 @@ public class ReflectUtil {
|
||||
}
|
||||
}
|
||||
|
||||
setAccessible(field);
|
||||
try {
|
||||
field.set(obj, value);
|
||||
field.set(obj instanceof Class ? null : obj, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new UtilException(e, "IllegalAccess for {}.{}", obj.getClass(), field.getName());
|
||||
throw new UtilException(e, "IllegalAccess for {}.{}", obj, field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,14 @@ public class DateUtilTest {
|
||||
Assert.assertEquals("2017-03-01 23:59:59", endOfDay.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void truncateTest(){
|
||||
String dateStr2 = "2020-02-29 12:59:34";
|
||||
Date date2 = DateUtil.parse(dateStr2);
|
||||
final DateTime dateTime = DateUtil.truncate(date2, DateField.MINUTE);
|
||||
Assert.assertEquals("2020-02-29 12:59:00", dateTime.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beginAndWeedTest() {
|
||||
String dateStr = "2017-03-01 22:33:23";
|
||||
|
@ -2,11 +2,10 @@ package cn.hutool.http;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.ssl.AndroidSupportSSLFactory;
|
||||
import cn.hutool.http.ssl.DefaultSSLInfo;
|
||||
import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
@ -14,6 +13,8 @@ import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.Proxy;
|
||||
@ -21,17 +22,14 @@ import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* http连接对象,对HttpURLConnection的包装
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class HttpConnection {
|
||||
|
||||
@ -41,9 +39,9 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 创建HttpConnection
|
||||
*
|
||||
*
|
||||
* @param urlStr URL
|
||||
* @param proxy 代理,无代理传{@code null}
|
||||
* @param proxy 代理,无代理传{@code null}
|
||||
* @return HttpConnection
|
||||
*/
|
||||
public static HttpConnection create(String urlStr, Proxy proxy) {
|
||||
@ -52,8 +50,8 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 创建HttpConnection
|
||||
*
|
||||
* @param url URL
|
||||
*
|
||||
* @param url URL
|
||||
* @param proxy 代理,无代理传{@code null}
|
||||
* @return HttpConnection
|
||||
*/
|
||||
@ -62,10 +60,11 @@ public class HttpConnection {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造HttpConnection
|
||||
*
|
||||
* @param url URL
|
||||
*
|
||||
* @param url URL
|
||||
* @param proxy 代理
|
||||
*/
|
||||
public HttpConnection(URL url, Proxy proxy) {
|
||||
@ -80,7 +79,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 初始化连接相关信息
|
||||
*
|
||||
*
|
||||
* @return HttpConnection
|
||||
* @since 4.4.1
|
||||
*/
|
||||
@ -98,10 +97,11 @@ public class HttpConnection {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Getters And Setters start
|
||||
|
||||
/**
|
||||
* 获取请求方法,GET/POST
|
||||
*
|
||||
* @return 请求方法,GET/POST
|
||||
*
|
||||
* @return 请求方法, GET/POST
|
||||
*/
|
||||
public Method getMethod() {
|
||||
return Method.valueOf(this.conn.getRequestMethod());
|
||||
@ -109,11 +109,23 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置请求方法
|
||||
*
|
||||
*
|
||||
* @param method 请求方法
|
||||
* @return 自己
|
||||
*/
|
||||
public HttpConnection setMethod(Method method) {
|
||||
if (Method.POST.equals(method) //
|
||||
|| Method.PUT.equals(method)//
|
||||
|| Method.PATCH.equals(method)//
|
||||
|| Method.DELETE.equals(method)) {
|
||||
this.conn.setUseCaches(false);
|
||||
|
||||
// 增加PATCH方法支持
|
||||
if (Method.PATCH.equals(method)) {
|
||||
allowPatch();
|
||||
}
|
||||
}
|
||||
|
||||
// method
|
||||
try {
|
||||
this.conn.setRequestMethod(method.toString());
|
||||
@ -121,18 +133,12 @@ public class HttpConnection {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
|
||||
if (Method.POST.equals(method) //
|
||||
|| Method.PUT.equals(method)//
|
||||
|| Method.PATCH.equals(method)//
|
||||
|| Method.DELETE.equals(method)) {
|
||||
this.conn.setUseCaches(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
*
|
||||
*
|
||||
* @return 请求URL
|
||||
*/
|
||||
public URL getUrl() {
|
||||
@ -141,7 +147,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获得代理
|
||||
*
|
||||
*
|
||||
* @return {@link Proxy}
|
||||
*/
|
||||
public Proxy getProxy() {
|
||||
@ -150,7 +156,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取HttpURLConnection对象
|
||||
*
|
||||
*
|
||||
* @return HttpURLConnection
|
||||
*/
|
||||
public HttpURLConnection getHttpURLConnection() {
|
||||
@ -160,12 +166,13 @@ public class HttpConnection {
|
||||
// --------------------------------------------------------------- Getters And Setters end
|
||||
|
||||
// ---------------------------------------------------------------- Headers start
|
||||
|
||||
/**
|
||||
* 设置请求头<br>
|
||||
* 当请求头存在时,覆盖之
|
||||
*
|
||||
* @param header 头名
|
||||
* @param value 头值
|
||||
*
|
||||
* @param header 头名
|
||||
* @param value 头值
|
||||
* @param isOverride 是否覆盖旧值
|
||||
* @return HttpConnection
|
||||
*/
|
||||
@ -184,9 +191,9 @@ public class HttpConnection {
|
||||
/**
|
||||
* 设置请求头<br>
|
||||
* 当请求头存在时,覆盖之
|
||||
*
|
||||
* @param header 头名
|
||||
* @param value 头值
|
||||
*
|
||||
* @param header 头名
|
||||
* @param value 头值
|
||||
* @param isOverride 是否覆盖旧值
|
||||
* @return HttpConnection
|
||||
*/
|
||||
@ -197,8 +204,8 @@ public class HttpConnection {
|
||||
/**
|
||||
* 设置请求头<br>
|
||||
* 不覆盖原有请求头
|
||||
*
|
||||
* @param headerMap 请求头
|
||||
*
|
||||
* @param headerMap 请求头
|
||||
* @param isOverride 是否覆盖
|
||||
* @return this
|
||||
*/
|
||||
@ -217,7 +224,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取Http请求头
|
||||
*
|
||||
*
|
||||
* @param name Header名
|
||||
* @return Http请求头值
|
||||
*/
|
||||
@ -227,7 +234,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取Http请求头
|
||||
*
|
||||
*
|
||||
* @param name Header名
|
||||
* @return Http请求头值
|
||||
*/
|
||||
@ -237,7 +244,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取所有Http请求头
|
||||
*
|
||||
*
|
||||
* @return Http请求头Map
|
||||
*/
|
||||
public Map<String, List<String>> headers() {
|
||||
@ -249,9 +256,9 @@ public class HttpConnection {
|
||||
/**
|
||||
* 设置https请求参数<br>
|
||||
* 有些时候htts请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现,此为sun内部api,按照普通http请求处理
|
||||
*
|
||||
*
|
||||
* @param hostnameVerifier 域名验证器,非https传入null
|
||||
* @param ssf SSLSocketFactory,非https传入null
|
||||
* @param ssf SSLSocketFactory,非https传入null
|
||||
* @return this
|
||||
* @throws HttpException KeyManagementException和NoSuchAlgorithmException异常包装
|
||||
*/
|
||||
@ -271,9 +278,9 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 关闭缓存
|
||||
*
|
||||
*
|
||||
* @return this
|
||||
* @see HttpURLConnection#setUseCaches(boolean)
|
||||
* @see HttpURLConnection#setUseCaches(boolean)
|
||||
*/
|
||||
public HttpConnection disableCache() {
|
||||
this.conn.setUseCaches(false);
|
||||
@ -282,7 +289,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置连接超时
|
||||
*
|
||||
*
|
||||
* @param timeout 超时
|
||||
* @return this
|
||||
*/
|
||||
@ -296,7 +303,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置读取超时
|
||||
*
|
||||
*
|
||||
* @param timeout 超时
|
||||
* @return this
|
||||
*/
|
||||
@ -310,7 +317,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置连接和读取的超时时间
|
||||
*
|
||||
*
|
||||
* @param timeout 超时时间
|
||||
* @return this
|
||||
*/
|
||||
@ -323,7 +330,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置Cookie
|
||||
*
|
||||
*
|
||||
* @param cookie Cookie
|
||||
* @return this
|
||||
*/
|
||||
@ -337,12 +344,12 @@ public class HttpConnection {
|
||||
/**
|
||||
* 采用流方式上传数据,无需本地缓存数据。<br>
|
||||
* HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。
|
||||
*
|
||||
*
|
||||
* @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式
|
||||
* @return this
|
||||
*/
|
||||
public HttpConnection setChunkedStreamingMode(int blockSize) {
|
||||
if(blockSize > 0) {
|
||||
if (blockSize > 0) {
|
||||
conn.setChunkedStreamingMode(blockSize);
|
||||
}
|
||||
return this;
|
||||
@ -350,7 +357,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 设置自动HTTP 30X跳转
|
||||
*
|
||||
*
|
||||
* @param isInstanceFollowRedirects 是否自定跳转
|
||||
* @return this
|
||||
*/
|
||||
@ -361,7 +368,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 连接
|
||||
*
|
||||
*
|
||||
* @return this
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
@ -371,10 +378,10 @@ public class HttpConnection {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 静默断开连接。不抛出异常
|
||||
*
|
||||
*
|
||||
* @return this
|
||||
* @since 4.6.0
|
||||
*/
|
||||
@ -384,13 +391,13 @@ public class HttpConnection {
|
||||
} catch (Throwable e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
*
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public HttpConnection disconnect() {
|
||||
@ -403,7 +410,7 @@ public class HttpConnection {
|
||||
/**
|
||||
* 获得输入流对象<br>
|
||||
* 输入流对象用于读取数据
|
||||
*
|
||||
*
|
||||
* @return 输入流对象
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
@ -416,7 +423,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 当返回错误代码时,获得错误内容流
|
||||
*
|
||||
*
|
||||
* @return 错误内容
|
||||
*/
|
||||
public InputStream getErrorStream() {
|
||||
@ -428,7 +435,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取输出流对象 输出流对象用于发送数据
|
||||
*
|
||||
*
|
||||
* @return OutputStream
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
@ -444,7 +451,7 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 获取响应码
|
||||
*
|
||||
*
|
||||
* @return 响应码
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
@ -459,7 +466,7 @@ public class HttpConnection {
|
||||
* 获得字符集编码<br>
|
||||
* 从Http连接的头信息中获得字符集<br>
|
||||
* 从ContentType中获取
|
||||
*
|
||||
*
|
||||
* @return 字符集编码
|
||||
*/
|
||||
public String getCharsetName() {
|
||||
@ -470,7 +477,7 @@ public class HttpConnection {
|
||||
* 获取字符集编码<br>
|
||||
* 从Http连接的头信息中获得字符集<br>
|
||||
* 从ContentType中获取
|
||||
*
|
||||
*
|
||||
* @return {@link Charset}编码
|
||||
* @since 3.0.9
|
||||
*/
|
||||
@ -501,10 +508,11 @@ public class HttpConnection {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Private Method start
|
||||
|
||||
/**
|
||||
* 初始化http或https请求参数<br>
|
||||
* 有些时候https请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现,此为sun内部api,按照普通http请求处理
|
||||
*
|
||||
*
|
||||
* @return {@link HttpURLConnection},https返回{@link HttpsURLConnection}
|
||||
*/
|
||||
private HttpURLConnection openHttp() throws IOException {
|
||||
@ -519,12 +527,30 @@ public class HttpConnection {
|
||||
|
||||
/**
|
||||
* 建立连接
|
||||
*
|
||||
*
|
||||
* @return {@link URLConnection}
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
private URLConnection openConnection() throws IOException {
|
||||
return (null == this.proxy) ? url.openConnection() : url.openConnection(this.proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加支持的METHOD方法
|
||||
* see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch
|
||||
*
|
||||
* @since 5.1.6
|
||||
*/
|
||||
private static void allowPatch() {
|
||||
final Field methodsField = ReflectUtil.getField(HttpURLConnection.class, "methods");
|
||||
if (null != methodsField) {
|
||||
// 去除final修饰
|
||||
ReflectUtil.setFieldValue(methodsField, "modifiers", methodsField.getModifiers() & ~Modifier.FINAL);
|
||||
final String[] methods = {
|
||||
"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
|
||||
};
|
||||
ReflectUtil.setFieldValue(null, methodsField, methods);
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------- Private Method end
|
||||
}
|
@ -338,13 +338,14 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest method(Method method) {
|
||||
if (Method.PATCH == method) {
|
||||
this.method = Method.POST;
|
||||
this.header("X-HTTP-Method-Override", "PATCH");
|
||||
} else {
|
||||
this.method = method;
|
||||
}
|
||||
// if (Method.PATCH == method) {
|
||||
// this.method = Method.POST;
|
||||
// this.header("X-HTTP-Method-Override", "PATCH");
|
||||
// } else {
|
||||
// this.method = method;
|
||||
// }
|
||||
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,24 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.StreamProgress;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.*;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -2,8 +2,8 @@ package cn.hutool.http;
|
||||
|
||||
/**
|
||||
* Http方法枚举
|
||||
* @author Looly
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public enum Method {
|
||||
GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT, PATCH
|
||||
|
@ -220,7 +220,7 @@ public class HttpUtilTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void patchTest() {
|
||||
String body = HttpRequest.post("https://www.baidu.com").execute().body();
|
||||
String body = HttpRequest.patch("https://www.baidu.com").execute().body();
|
||||
Console.log(body);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user