This commit is contained in:
Looly 2022-10-26 21:48:49 +08:00
parent ad5296866d
commit 11f47e5b0f
4 changed files with 73 additions and 56 deletions

View File

@ -84,7 +84,7 @@ public class FieldUtil {
public static Field getDeClearField(final Class<?> beanClass, final String name) {
try {
return beanClass.getDeclaredField(name);
} catch (NoSuchFieldException e) {
} catch (final NoSuchFieldException e) {
return null;
}
}
@ -124,7 +124,7 @@ public class FieldUtil {
* 获得一个类中所有满足条件的字段列表包括其父类中的字段<br>
* 如果子类与父类中存在同名字段则这两个字段同时存在子类字段在前父类字段在后
*
* @param beanClass
* @param beanClass
* @param fieldPredicate field过滤器过滤掉不需要的field{@link Predicate#test(Object)}{@code true}保留null表示全部保留
* @return 字段列表
* @throws SecurityException 安全检查异常
@ -254,6 +254,17 @@ public class FieldUtil {
setFieldValue(obj, field, value);
}
/**
* 设置静态static字段值
*
* @param field 字段
* @param value 值类型必须与字段类型匹配不会自动转换对象类型
* @throws UtilException UtilException 包装IllegalAccessException异常
*/
public static void setStaticFieldValue(final Field field, final Object value) throws UtilException {
setFieldValue(null, field, value);
}
/**
* 设置字段值
*

View File

@ -1,17 +1,11 @@
package cn.hutool.http;
import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.client.cookie.GlobalCookieManager;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.CookieManager;
import java.net.HttpURLConnection;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* HTTP 全局参数配置
@ -31,7 +25,6 @@ public class HttpGlobalConfig implements Serializable {
* 底层调用{@link HttpURLConnection#setConnectTimeout(int)} 同时设置: 连接超时
*/
private static int timeout = -1;
private static boolean isAllowPatch = false;
private static String boundary = "--------------------Hutool_" + RandomUtil.randomString(16);
private static int maxRedirectCount = 0;
private static boolean ignoreEOFError = true;
@ -182,48 +175,4 @@ public class HttpGlobalConfig implements Serializable {
synchronized public static void closeCookie() {
GlobalCookieManager.setCookieManager(null);
}
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
*/
public static void allowPatch(){
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
doAllowPatch();
return null;
});
}
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
*
* @since 5.7.4
*/
synchronized private static void doAllowPatch() {
if (isAllowPatch) {
return;
}
final Field methodsField = FieldUtil.getField(HttpURLConnection.class, "methods");
if (null == methodsField) {
throw new HttpException("None static field [methods] with Java version: [{}]", System.getProperty("java.version"));
}
// 去除final修饰
FieldUtil.setFieldValue(methodsField, "modifiers", methodsField.getModifiers() & ~Modifier.FINAL);
final String[] methods = {
"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
};
FieldUtil.setFieldValue(null, methodsField, methods);
// 检查注入是否成功
final Object staticFieldValue = FieldUtil.getStaticFieldValue(methodsField);
if (false == ArrayUtil.equals(methods, staticFieldValue)) {
throw new HttpException("Inject value to field [methods] failed!");
}
isAllowPatch = true;
}
}

View File

@ -5,10 +5,9 @@ import cn.hutool.core.net.url.URLUtil;
import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.http.meta.Header;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpGlobalConfig;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.meta.Header;
import cn.hutool.http.meta.Method;
import cn.hutool.http.ssl.DefaultSSLInfo;
@ -125,7 +124,7 @@ public class HttpConnection {
// 增加PATCH方法支持
if (Method.PATCH.equals(method)) {
HttpGlobalConfig.allowPatch();
HttpUrlConnectionUtil.allowPatch();
}
}

View File

@ -0,0 +1,58 @@
package cn.hutool.http.client.engine.jdk;
import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.reflect.ModifierUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.SystemUtil;
import cn.hutool.http.HttpException;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* 针对{@link HttpURLConnection}相关工具
*
* @author looly
* @since 6.0.0
*/
public class HttpUrlConnectionUtil {
private static final String[] METHODS = {
"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
};
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
*/
public static void allowPatch() {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
doAllowPatch();
return null;
});
}
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
*
* @since 5.7.4
*/
synchronized private static void doAllowPatch() {
final Field methodsField = FieldUtil.getField(HttpURLConnection.class, "methods");
if (null == methodsField) {
throw new HttpException("None static field [methods] with Java version: [{}]", SystemUtil.get("java.version"));
}
final Object staticFieldValue = FieldUtil.getStaticFieldValue(methodsField);
if (false == ArrayUtil.equals(METHODS, staticFieldValue)) {
// 去除final修饰
ModifierUtil.removeFinalModify(methodsField);
FieldUtil.setStaticFieldValue(methodsField, METHODS);
}
}
}