Browse Source

fix http bug

Looly 5 years ago
parent
commit
3e05c5b396

+ 1 - 0
CHANGELOG.md

@@ -21,6 +21,7 @@
 * 【core  】     重新整理农历节假日,解决一个pr过来的玩笑导致的问题
 * 【poi   】     修复ExcelFileUtil.isXls判断问题(pr#1055@Github)
 * 【poi   】     修复CglibUtil.copyList参数错误导致的问题
+* 【http  】     修复GET请求附带body导致变POST的问题
 
 -------------------------------------------------------------------------------------------------------------
 

+ 1 - 1
hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java

@@ -1350,7 +1350,7 @@ public class CollUtil {
 	 * @return 抽取后的新列表
 	 * @since 5.3.5
 	 */
-	public static <T, R> List<R> map(Iterable<T> collection, Function<T, R> func, boolean ignoreNull) {
+	public static <T, R> List<R> map(Iterable<T> collection, Function<? super T, ? extends R> func, boolean ignoreNull) {
 		final List<R> fieldValueList = new ArrayList<>();
 		if (null == collection) {
 			return fieldValueList;

+ 30 - 1
hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java

@@ -11,7 +11,17 @@ import cn.hutool.core.lang.Matcher;
 
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
 
 /**
  * 数组工具类
@@ -4274,4 +4284,23 @@ public class ArrayUtil {
 	public static <T> boolean isAllNotNull(T... array) {
 		return false == hasNull(array);
 	}
+
+	/**
+	 * 按照指定规则,将一种类型的数组转换为另一种类型
+	 *
+	 * @param array 被转换的数组
+	 * @param targetComponentType 目标的元素类型
+	 * @param func 转换规则函数
+	 * @param <T> 原数组类型
+	 * @param <R> 目标数组类型
+	 * @return 转换后的数组
+	 * @since 5.4.2
+	 */
+	public static <T, R> R[] map(T[] array, Class<R> targetComponentType, Function<? super T, ? extends R> func){
+		final R[] result = newArray(targetComponentType, array.length);
+		for(int i=0; i< array.length; i++){
+			result[i] = func.apply(array[i]);
+		}
+		return result;
+	}
 }

+ 8 - 6
hutool-core/src/main/java/cn/hutool/core/util/TypeUtil.java

@@ -295,7 +295,7 @@ public class TypeUtil {
 	 * @return 给定泛型参数对应的实际类型,如果无对应类型,返回null
 	 * @since 5.4.1
 	 */
-	public static TableMap<TypeVariable<?>, Type> getActualTypeMap(Type actualType, Class<?> typeDefineClass) {
+	public static TableMap<String, Type> getActualTypeMap(Type actualType, Class<?> typeDefineClass) {
 		if (false == typeDefineClass.isAssignableFrom(getClass(actualType))) {
 			throw new IllegalArgumentException("Parameter [superClass] must be assignable from [clazz]");
 		}
@@ -305,13 +305,14 @@ public class TypeUtil {
 		if (ArrayUtil.isEmpty(typeVars)) {
 			return new TableMap<>(0);
 		}
+
 		// 实际类型列表
 		final Type[] actualTypeArguments = TypeUtil.getTypeArguments(actualType);
 		if (ArrayUtil.isEmpty(actualTypeArguments)) {
 			return new TableMap<>(0);
 		}
 
-		return new TableMap<>(typeVars, actualTypeArguments);
+		return new TableMap<>(ArrayUtil.map(typeVars, String.class, TypeVariable::getName), actualTypeArguments);
 	}
 
 	/**
@@ -331,13 +332,14 @@ public class TypeUtil {
 	 * @since 4.5.7
 	 */
 	public static Type[] getActualTypes(Type actualType, Class<?> typeDefineClass, Type... typeVariables) {
-		final TableMap<TypeVariable<?>, Type> tableMap = getActualTypeMap(actualType, typeDefineClass);
+		final TableMap<String, Type> tableMap = getActualTypeMap(actualType, typeDefineClass);
 
 		// 查找方法定义所在类或接口中此泛型参数的位置
 		final Type[] result = new Type[typeVariables.length];
 		for (int i = 0; i < typeVariables.length; i++) {
-			//noinspection SuspiciousMethodCalls
-			result[i] = (typeVariables[i] instanceof TypeVariable) ? tableMap.get(typeVariables[i]) : typeVariables[i];
+			result[i] = (typeVariables[i] instanceof TypeVariable)
+					? tableMap.get(((TypeVariable<?>) typeVariables[i]).getName())
+					: typeVariables[i];
 		}
 		return result;
 	}
@@ -359,7 +361,7 @@ public class TypeUtil {
 	 * @since 4.5.2
 	 */
 	public static Type getActualType(Type actualType, Class<?> typeDefineClass, Type typeVariable) {
-		Type[] types = getActualTypes(actualType, typeDefineClass, typeVariable);
+		final Type[] types = getActualTypes(actualType, typeDefineClass, typeVariable);
 		if (ArrayUtil.isNotEmpty(types)) {
 			return types[0];
 		}

+ 4 - 2
hutool-core/src/test/java/cn/hutool/core/util/TypeUtilTest.java

@@ -60,10 +60,12 @@ public class TypeUtilTest {
 
 	@Test
 	public void getActualTypesTest(){
-		final Type id = TypeUtil.getActualType(
+		final Type idType = TypeUtil.getActualType(
 				Station.class,
-				Entity.class,
+				Tree.class,
 				TypeUtil.getFieldType(Station.class, "id"));
+
+		Assert.assertEquals(Long.class, idType);
 	}
 
 	public static class Station extends Tree<Station, Long>{

+ 13 - 1
hutool-http/src/main/java/cn/hutool/http/HttpConnection.java

@@ -444,9 +444,21 @@ public class HttpConnection {
 			throw new IOException("HttpURLConnection has not been initialized.");
 		}
 
+		final Method method = getMethod();
+
 		// 当有写出需求时,自动打开之
 		this.conn.setDoOutput(true);
-		return this.conn.getOutputStream();
+		final OutputStream out = this.conn.getOutputStream();
+
+		// 解决在Rest请求中,GET请求附带body导致GET请求被强制转换为POST
+		// 在sun.net.www.protocol.http.HttpURLConnection.getOutputStream0方法中,会把GET方法
+		// 修改为POST,而且无法调用setRequestMethod方法修改,因此此处使用反射强制修改字段属性值
+		// https://stackoverflow.com/questions/978061/http-get-with-request-body/983458
+		if(method == Method.GET && method != getMethod()){
+			ReflectUtil.setFieldValue(this.conn, "method", Method.GET.name());
+		}
+
+		return out;
 	}
 
 	/**

+ 28 - 4
hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java

@@ -6,18 +6,21 @@ import cn.hutool.core.lang.Console;
 import cn.hutool.core.util.CharsetUtil;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
 import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
+import cn.hutool.json.JSONUtil;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 /**
  * {@link HttpRequest}单元测试
- * 
- * @author Looly
  *
+ * @author Looly
  */
 public class HttpRequestTest {
 	final String url = "http://photo.qzone.qq.com/fcgi-bin/fcg_list_album?uin=88888&outstyle=2";
@@ -43,7 +46,7 @@ public class HttpRequestTest {
 	@Ignore
 	public void toStringTest() {
 		String url = "http://gc.ditu.aliyun.com/geocoding?ccc=你好";
-		
+
 		HttpRequest request = HttpRequest.get(url).body("a=乌海");
 		Console.log(request.toString());
 	}
@@ -105,8 +108,29 @@ public class HttpRequestTest {
 
 	@Test
 	@Ignore
-	public void bodyTest(){
+	public void bodyTest() {
 		String ddddd1 = HttpRequest.get("https://baijiahao.baidu.com/s").body("id=1625528941695652600").execute().body();
 		Console.log(ddddd1);
 	}
+
+	/**
+	 * 测试GET请求附带body体是否会变更为POST
+	 */
+	@Test
+	@Ignore
+	public void getLocalTest() {
+		List<String> list = new ArrayList<>();
+		list.add("hhhhh");
+		list.add("sssss");
+
+		Map<String, Object> map = new HashMap<>(16);
+		map.put("recordId", "12321321");
+		map.put("page", "1");
+		map.put("size", "2");
+		map.put("sizes", list);
+
+		String s = JSONUtil.toJsonStr(map);
+		HttpRequest request = HttpUtil.createGet("http://localhost:8888/get");
+		Console.log(request.execute().body());
+	}
 }