From b67464e6c1f2c5e507dda3b90c9a8f62998d1739 Mon Sep 17 00:00:00 2001 From: liupeng Date: Tue, 7 Mar 2023 18:29:26 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/date/TimeUtil.java | 38 +++++++++++-------- .../cn/hutool/core/date/TimeUtilTest.java | 24 ++++++++++++ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java index fbc0a95c0..19b729ada 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java @@ -4,27 +4,14 @@ import cn.hutool.core.date.format.GlobalCustomFormat; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ObjUtil; -import java.time.DayOfWeek; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.Period; -import java.time.ZoneId; -import java.time.ZonedDateTime; +import java.time.*; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoField; -import java.time.temporal.ChronoUnit; -import java.time.temporal.Temporal; -import java.time.temporal.TemporalAccessor; -import java.time.temporal.TemporalAdjusters; -import java.time.temporal.TemporalUnit; -import java.time.temporal.WeekFields; +import java.time.temporal.*; import java.util.Date; import java.util.TimeZone; +import java.util.function.Function; /** * JDK8+中的{@link java.time} 工具类封装 @@ -355,6 +342,25 @@ public class TimeUtil extends TemporalAccessorUtil { return format(date, DatePattern.NORM_DATE_FORMATTER); } + + /** + * 格式化时间函数 + * + * @return 格式化时间的函数 + */ + public static Function formatTimeFunction(DateTimeFormatter dateTimeFormatter) { + return time -> format(time, dateTimeFormatter); + } + + /** + * 格式化日期函数 + * + * @return 格式化时间的函数 + */ + public static Function formatDateFunction(DateTimeFormatter dateTimeFormatter) { + return date -> format(date, dateTimeFormatter); + } + /** * 日期偏移,根据field不同加不同值(偏移会修改传入的对象) * diff --git a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java index dcb304acc..7a825c4de 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java @@ -10,7 +10,10 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class TimeUtilTest { @@ -319,4 +322,25 @@ public class TimeUtilTest { Assert.assertThrows(IllegalArgumentException.class, () -> TimeUtil.isIn(begin, null, end, false, false)); Assert.assertThrows(IllegalArgumentException.class, () -> TimeUtil.isIn(begin, begin, null, false, false)); } + + + @Test + public void formatDateFunctionTest() { + List dateStrList = Stream.of("2023-03-01", "2023-03-02") + .map(LocalDate::parse) + .map(TimeUtil.formatDateFunction(DatePattern.CHINESE_DATE_FORMATTER)) + .collect(Collectors.toList()); + Assert.assertEquals("2023年03月01日", dateStrList.get(0)); + Assert.assertEquals("2023年03月02日", dateStrList.get(1)); + } + + @Test + public void formatTimeFunctionTest() { + List dateStrList = Stream.of("2023-03-01T12:23:56", "2023-03-02T12:23:56") + .map(LocalDateTime::parse) + .map(TimeUtil.formatTimeFunction(DatePattern.CHINESE_DATE_FORMATTER)) + .collect(Collectors.toList()); + Assert.assertEquals("2023年03月01日", dateStrList.get(0)); + Assert.assertEquals("2023年03月02日", dateStrList.get(1)); + } } From 5ac1c818126d4440d42ddd6f93a0e681f902bb0b Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 8 Mar 2023 23:10:05 +0800 Subject: [PATCH 2/4] add test --- .../cn/hutool/core/lang/func/LambdaUtilTest.java | 13 +++++++++++++ .../test/java/cn/hutool/json/jwt/JWTTest.java | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java index c525fad3f..1014d9780 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java @@ -282,4 +282,17 @@ public class LambdaUtilTest { REF_invokeSpecial, REF_newInvokeSpecial, } + + @Test + public void lambdaClassNameTest() { + final String lambdaClassName1 = LambdaUtilTestHelper.getLambdaClassName(MyTeacher::getAge); + final String lambdaClassName2 = LambdaUtilTestHelper.getLambdaClassName(MyTeacher::getAge); + Assert.assertNotEquals(lambdaClassName1, lambdaClassName2); + } + + static class LambdaUtilTestHelper { + public static

String getLambdaClassName(final Function func) { + return func.getClass().getName(); + } + } } diff --git a/hutool-json/src/test/java/cn/hutool/json/jwt/JWTTest.java b/hutool-json/src/test/java/cn/hutool/json/jwt/JWTTest.java index 0d2808651..6028bdd72 100755 --- a/hutool-json/src/test/java/cn/hutool/json/jwt/JWTTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/jwt/JWTTest.java @@ -172,4 +172,20 @@ public class JWTTest { final Object test2 = JWT.of(sign).getPayload().getClaim("test2"); Assert.assertEquals(Long.class, test2.getClass()); } + + @Test + public void getLongTest(){ + final String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" + + ".eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJhZG1pbiIsImRldmljZSI6ImRlZmF1bHQtZGV2aWNlIiwiZWZmIjoxNjc4Mjg1NzEzOTM1LCJyblN0ciI6IkVuMTczWFhvWUNaaVZUWFNGOTNsN1pabGtOalNTd0pmIn0" + + ".wRe2soTaWYPhwcjxdzesDi1BgEm9D61K-mMT3fPc4YM" + + ""; + + final JWT jwt = JWTUtil.parseToken(rightToken); + + Assert.assertEquals( + "{\"loginType\":\"login\",\"loginId\":\"admin\",\"device\":\"default-device\"," + + "\"eff\":1678285713935,\"rnStr\":\"En173XXoYCZiVTXSF93l7ZZlkNjSSwJf\"}", + jwt.getPayloads().toString()); + Assert.assertEquals(Long.valueOf(1678285713935L), jwt.getPayloads().getLong("eff")); + } } From e215f22292c06f4a2ed34a444e0439a4917a7a42 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 8 Mar 2023 23:36:21 +0800 Subject: [PATCH 3/4] fix code --- .../java/cn/hutool/core/date/TimeUtil.java | 15 +--- .../cn/hutool/core/lang/func/LambdaUtil.java | 80 ++++++++++++++----- .../hutool/core/lang/func/PredicateUtil.java | 7 ++ .../core/lang/func/SerBinaryOperator.java | 8 +- .../cn/hutool/core/lang/func/SerConsumer.java | 2 +- .../hutool/core/lang/func/SerConsumer3.java | 8 +- .../cn/hutool/core/date/TimeUtilTest.java | 8 +- 7 files changed, 85 insertions(+), 43 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java index 19b729ada..b045f2838 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java @@ -1,6 +1,7 @@ package cn.hutool.core.date; import cn.hutool.core.date.format.GlobalCustomFormat; +import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ObjUtil; @@ -346,19 +347,11 @@ public class TimeUtil extends TemporalAccessorUtil { /** * 格式化时间函数 * + * @param dateTimeFormatter {@link DateTimeFormatter} * @return 格式化时间的函数 */ - public static Function formatTimeFunction(DateTimeFormatter dateTimeFormatter) { - return time -> format(time, dateTimeFormatter); - } - - /** - * 格式化日期函数 - * - * @return 格式化时间的函数 - */ - public static Function formatDateFunction(DateTimeFormatter dateTimeFormatter) { - return date -> format(date, dateTimeFormatter); + public static Function formatFunc(final DateTimeFormatter dateTimeFormatter) { + return LambdaUtil.toFunction(TimeUtil::format, dateTimeFormatter); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java index 43bb2733b..19ccd47d2 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java @@ -13,8 +13,7 @@ import java.lang.invoke.SerializedLambda; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.function.BiConsumer; -import java.util.function.Function; +import java.util.function.*; /** * Lambda相关工具类 @@ -34,12 +33,12 @@ public class LambdaUtil { * MyTeacher myTeacher = new MyTeacher(); * Class supplierClass = LambdaUtil.getRealClass(myTeacher::getAge); * Assert.assertEquals(MyTeacher.class, supplierClass); - * } + * } * *

  • 引用静态无参方法:
    {@code
     	 * 			Class staticSupplierClass = LambdaUtil.getRealClass(MyTeacher::takeAge);
     	 * 			Assert.assertEquals(MyTeacher.class, staticSupplierClass);
    -	 * 			}
    + * } *
  • * * 在以下场景无法获取到正确类型 @@ -123,7 +122,7 @@ public class LambdaUtil { * * * @param func 函数 - * @param lambda的类型 + * @param lambda的类型 * @return 方法名称 * @throws IllegalArgumentException 非Getter或Setter方法 * @since 5.7.23 @@ -136,8 +135,8 @@ public class LambdaUtil { * 等效于 Obj::getXxx * * @param getMethod getter方法 - * @param 调用getter方法对象类型 - * @param getter方法返回值类型 + * @param 调用getter方法对象类型 + * @param getter方法返回值类型 * @return Obj::getXxx */ @SuppressWarnings("unchecked") @@ -148,10 +147,10 @@ public class LambdaUtil { /** * 等效于 Obj::getXxx * - * @param clazz 调用getter方法对象类 + * @param clazz 调用getter方法对象类 * @param fieldName 字段名称 - * @param 调用getter方法对象类型 - * @param getter方法返回值类型 + * @param 调用getter方法对象类型 + * @param getter方法返回值类型 * @return Obj::getXxx */ @SuppressWarnings("unchecked") @@ -163,8 +162,8 @@ public class LambdaUtil { * 等效于 Obj::setXxx * * @param setMethod setter方法 - * @param 调用setter方法对象类型 - * @param

    setter方法返回的值类型 + * @param 调用setter方法对象类型 + * @param

    setter方法返回的值类型 * @return Obj::setXxx */ @SuppressWarnings("unchecked") @@ -175,10 +174,10 @@ public class LambdaUtil { /** * Obj::setXxx * - * @param clazz 调用setter方法对象类 + * @param clazz 调用setter方法对象类 * @param fieldName 字段名称 - * @param 调用setter方法对象类型 - * @param

    setter方法返回的值类型 + * @param 调用setter方法对象类型 + * @param

    setter方法返回的值类型 * @return Obj::setXxx */ @SuppressWarnings("unchecked") @@ -189,17 +188,60 @@ public class LambdaUtil { /** * 等效于 Obj::method * - * @param lambdaType 接受lambda的函数式接口类型 - * @param clazz 调用类 - * @param methodName 方法名 + * @param lambdaType 接受lambda的函数式接口类型 + * @param clazz 调用类 + * @param methodName 方法名 * @param paramsTypes 方法参数类型数组 - * @param 函数式接口类型 + * @param 函数式接口类型 * @return Obj::method */ public static F build(final Class lambdaType, final Class clazz, final String methodName, final Class... paramsTypes) { return LambdaFactory.build(lambdaType, clazz, methodName, paramsTypes); } + /** + * 通过自定义固定参数,将{@link BiFunction}转换为{@link Function} + * + * @param biFunction {@link BiFunction} + * @param param 参数 + * @param 参数类型 + * @param 参数2类型 + * @param 返回值类型 + * @return {@link Function} + * @since 6.0.0 + */ + public static Function toFunction(final BiFunction biFunction, final U param) { + return (t) -> biFunction.apply(t, param); + } + + /** + * 通过自定义固定参数,将{@link BiPredicate}转换为{@link Predicate} + * + * @param biPredicate {@link BiFunction} + * @param param 参数 + * @param 参数类型 + * @param 参数2类型 + * @return {@link Predicate} + * @since 6.0.0 + */ + public static Predicate toPredicate(final BiPredicate biPredicate, final U param) { + return (t) -> biPredicate.test(t, param); + } + + /** + * 通过自定义固定参数,将{@link BiConsumer}转换为{@link Consumer} + * + * @param biConsumer {@link BiConsumer} + * @param param 参数 + * @param 参数类型 + * @param 参数2类型 + * @return {@link Consumer} + * @since 6.0.0 + */ + public static Consumer toPredicate(final BiConsumer biConsumer, final U param) { + return (t) -> biConsumer.accept(t, param); + } + //region Private methods /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/PredicateUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/PredicateUtil.java index 580150885..153ddf980 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/PredicateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/PredicateUtil.java @@ -12,6 +12,13 @@ import java.util.function.Predicate; */ public class PredicateUtil { + /** + * 反向条件 + * + * @param predicate 条件 + * @param 参数类型 + * @return 反向条件 {@link Predicate} + */ public static Predicate negate(final Predicate predicate) { return predicate.negate(); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerBinaryOperator.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerBinaryOperator.java index 50d1f6d6c..31f737aa3 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerBinaryOperator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerBinaryOperator.java @@ -10,9 +10,9 @@ import java.util.function.BinaryOperator; /** * SerBinaryOperator * - * @author VampireAchao - * @since 2022/6/8 * @param 参数和返回值类型 + * @author VampireAchao + * @see BinaryOperator */ @FunctionalInterface public interface SerBinaryOperator extends BinaryOperator, Serializable { @@ -44,7 +44,7 @@ public interface SerBinaryOperator extends BinaryOperator, Serializable { } /** - * Returns a {@link SerBinaryOperator} which returns the lesser of two elements + * Returns a {@code SerBinaryOperator} which returns the lesser of two elements * according to the specified {@code Comparator}. * * @param the type of the input arguments of the comparator @@ -59,7 +59,7 @@ public interface SerBinaryOperator extends BinaryOperator, Serializable { } /** - * Returns a {@link SerBinaryOperator} which returns the greater of two elements + * Returns a {@code SerBinaryOperator} which returns the greater of two elements * according to the specified {@code Comparator}. * * @param the type of the input arguments of the comparator diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer.java index e9380ea0f..b4d798ddc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer.java @@ -66,7 +66,7 @@ public interface SerConsumer extends Consumer, Serializable { */ default SerConsumer andThen(final SerConsumer after) { Objects.requireNonNull(after); - return (T t) -> { + return (final T t) -> { accept(t); after.accept(t); }; diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer3.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer3.java index 888d503d1..dd1200c62 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer3.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/SerConsumer3.java @@ -34,10 +34,10 @@ public interface SerConsumer3 extends Serializable { * @param p2 参数二 * @param p3 参数三 */ - default void accept(P1 p1, P2 p2, P3 p3) { + default void accept(final P1 p1, final P2 p2, final P3 p3) { try { accepting(p1, p2, p3); - } catch (Exception e) { + } catch (final Exception e) { throw new UtilException(e); } } @@ -54,9 +54,9 @@ public interface SerConsumer3 extends Serializable { * operation followed by the {@code after} operation * @throws NullPointerException if {@code after} is null */ - default SerConsumer3 andThen(SerConsumer3 after) { + default SerConsumer3 andThen(final SerConsumer3 after) { Objects.requireNonNull(after); - return (P1 p1, P2 p2, P3 p3) -> { + return (final P1 p1, final P2 p2, final P3 p3) -> { accept(p1, p2, p3); after.accept(p1, p2, p3); }; diff --git a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java index 7a825c4de..75f8f8aa1 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java @@ -326,9 +326,9 @@ public class TimeUtilTest { @Test public void formatDateFunctionTest() { - List dateStrList = Stream.of("2023-03-01", "2023-03-02") + final List dateStrList = Stream.of("2023-03-01", "2023-03-02") .map(LocalDate::parse) - .map(TimeUtil.formatDateFunction(DatePattern.CHINESE_DATE_FORMATTER)) + .map(TimeUtil.formatFunc(DatePattern.CHINESE_DATE_FORMATTER)) .collect(Collectors.toList()); Assert.assertEquals("2023年03月01日", dateStrList.get(0)); Assert.assertEquals("2023年03月02日", dateStrList.get(1)); @@ -336,9 +336,9 @@ public class TimeUtilTest { @Test public void formatTimeFunctionTest() { - List dateStrList = Stream.of("2023-03-01T12:23:56", "2023-03-02T12:23:56") + final List dateStrList = Stream.of("2023-03-01T12:23:56", "2023-03-02T12:23:56") .map(LocalDateTime::parse) - .map(TimeUtil.formatTimeFunction(DatePattern.CHINESE_DATE_FORMATTER)) + .map(TimeUtil.formatFunc(DatePattern.CHINESE_DATE_FORMATTER)) .collect(Collectors.toList()); Assert.assertEquals("2023年03月01日", dateStrList.get(0)); Assert.assertEquals("2023年03月02日", dateStrList.get(1)); From 09b5cc671e7ed2a6cde3ef09c3768180a209eaa3 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 8 Mar 2023 23:51:29 +0800 Subject: [PATCH 4/4] add test --- .../main/java/cn/hutool/http/HttpConfig.java | 278 ------------------ .../http/server/RedirectServerTest.java | 27 ++ 2 files changed, 27 insertions(+), 278 deletions(-) delete mode 100755 hutool-http/src/main/java/cn/hutool/http/HttpConfig.java create mode 100644 hutool-http/src/test/java/cn/hutool/http/server/RedirectServerTest.java diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpConfig.java b/hutool-http/src/main/java/cn/hutool/http/HttpConfig.java deleted file mode 100755 index 36cc0af66..000000000 --- a/hutool-http/src/main/java/cn/hutool/http/HttpConfig.java +++ /dev/null @@ -1,278 +0,0 @@ -package cn.hutool.http; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.net.ssl.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 of() { - return new HttpConfig(); - } - - /** - * 默认连接超时 - */ - public int connectionTimeout = HttpGlobalConfig.getTimeout(); - /** - * 默认读取超时 - */ - public int readTimeout = HttpGlobalConfig.getTimeout(); - - /** - * 是否禁用缓存 - */ - public boolean isDisableCache; - - /** - * 最大重定向次数 - */ - public int maxRedirectCount = HttpGlobalConfig.getMaxRedirectCount(); - - /** - * 代理 - */ - public Proxy proxy; - - /** - * HostnameVerifier,用于HTTPS安全连接 - */ - public HostnameVerifier hostnameVerifier; - /** - * SSLSocketFactory,用于HTTPS安全连接 - */ - public SSLSocketFactory ssf; - - /** - * Chuncked块大小,0或小于0表示不设置Chuncked模式 - */ - public int blockSize; - - /** - * 获取是否忽略响应读取时可能的EOF异常。
    - * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
    - * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 - */ - boolean ignoreEOFError = HttpGlobalConfig.isIgnoreEOFError(); - /** - * 获取是否忽略解码URL,包括URL中的Path部分和Param部分。
    - * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
    - * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 - */ - boolean decodeUrl = HttpGlobalConfig.isDecodeUrl(); - - /** - * 重定向时是否使用拦截器 - */ - public boolean interceptorOnRedirect; - - /** - * 设置超时,单位:毫秒
    - * 超时包括: - * - *

    -	 * 1. 连接超时
    -	 * 2. 读取响应超时
    -	 * 
    - * - * @param milliseconds 超时毫秒数 - * @return this - * @see #setConnectionTimeout(int) - * @see #setReadTimeout(int) - */ - public HttpConfig timeout(final int milliseconds) { - setConnectionTimeout(milliseconds); - setReadTimeout(milliseconds); - return this; - } - - /** - * 设置连接超时,单位:毫秒 - * - * @param milliseconds 超时毫秒数 - * @return this - */ - public HttpConfig setConnectionTimeout(final int milliseconds) { - this.connectionTimeout = milliseconds; - return this; - } - - /** - * 设置读取超时,单位:毫秒 - * - * @param milliseconds 超时毫秒数 - * @return this - */ - public HttpConfig setReadTimeout(final int milliseconds) { - this.readTimeout = milliseconds; - return this; - } - - /** - * 禁用缓存 - * - * @return this - */ - public HttpConfig disableCache() { - this.isDisableCache = true; - return this; - } - - /** - * 设置最大重定向次数
    - * 如果次数小于1则表示不重定向,大于等于1表示打开重定向 - * - * @param maxRedirectCount 最大重定向次数 - * @return this - */ - public HttpConfig setMaxRedirectCount(final int maxRedirectCount) { - this.maxRedirectCount = Math.max(maxRedirectCount, 0); - return this; - } - - /** - * 设置域名验证器
    - * 只针对HTTPS请求,如果不设置,不做验证,所有域名被信任 - * - * @param hostnameVerifier HostnameVerifier - * @return this - */ - public HttpConfig setHostnameVerifier(final HostnameVerifier hostnameVerifier) { - // 验证域 - this.hostnameVerifier = hostnameVerifier; - return this; - } - - /** - * 设置Http代理 - * - * @param host 代理 主机 - * @param port 代理 端口 - * @return this - */ - public HttpConfig setHttpProxy(final String host, final 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(final Proxy proxy) { - this.proxy = proxy; - return this; - } - - /** - * 设置SSLSocketFactory
    - * 只针对HTTPS请求,如果不设置,使用默认的SSLSocketFactory
    - * 默认SSLSocketFactory为:SSLSocketFactoryBuilder.create().build(); - * - * @param ssf SSLScketFactory - * @return this - */ - public HttpConfig setSSLSocketFactory(final SSLSocketFactory ssf) { - this.ssf = ssf; - return this; - } - - /** - * 设置HTTPS安全连接协议,只针对HTTPS请求,可以使用的协议包括:
    - * 此方法调用后{@link #setSSLSocketFactory(SSLSocketFactory)} 将被覆盖。 - * - *
    -	 * 1. TLSv1.2
    -	 * 2. TLSv1.1
    -	 * 3. SSLv3
    -	 * ...
    -	 * 
    - * - * @param protocol 协议 - * @return this - * @see SSLUtil#createSSLContext(String) - * @see #setSSLSocketFactory(SSLSocketFactory) - */ - public HttpConfig setSSLProtocol(final String protocol) { - Assert.notBlank(protocol, "protocol must be not blank!"); - setSSLSocketFactory(SSLUtil.createSSLContext(protocol).getSocketFactory()); - return this; - } - - /** - * 采用流方式上传数据,无需本地缓存数据。
    - * HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。 - * - * @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式 - * @return this - */ - public HttpConfig setBlockSize(final int blockSize) { - this.blockSize = blockSize; - return this; - } - - /** - * 设置是否忽略响应读取时可能的EOF异常。
    - * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
    - * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 - * - * @param ignoreEOFError 是否忽略响应读取时可能的EOF异常。 - * @return this - * @since 5.7.20 - */ - public HttpConfig setIgnoreEOFError(final boolean ignoreEOFError) { - this.ignoreEOFError = ignoreEOFError; - return this; - } - - /** - * 设置是否忽略解码URL,包括URL中的Path部分和Param部分。
    - * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
    - * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 - * - * @param decodeUrl 是否忽略解码URL - * @return this - */ - public HttpConfig setDecodeUrl(final boolean decodeUrl) { - this.decodeUrl = decodeUrl; - return this; - } - - /** - * 重定向时是否使用拦截器 - * - * @param interceptorOnRedirect 重定向时是否使用拦截器 - * @return this - */ - public HttpConfig setInterceptorOnRedirect(final boolean interceptorOnRedirect) { - this.interceptorOnRedirect = interceptorOnRedirect; - return this; - } - - /** - * 获取是否忽略响应读取时可能的EOF异常。 - * - * @return 是否忽略响应读取时可能的EOF异常。 - */ - public boolean isIgnoreEOFError() { - return ignoreEOFError; - } -} diff --git a/hutool-http/src/test/java/cn/hutool/http/server/RedirectServerTest.java b/hutool-http/src/test/java/cn/hutool/http/server/RedirectServerTest.java new file mode 100644 index 000000000..2e1896ede --- /dev/null +++ b/hutool-http/src/test/java/cn/hutool/http/server/RedirectServerTest.java @@ -0,0 +1,27 @@ +package cn.hutool.http.server; + +import cn.hutool.core.lang.Console; +import cn.hutool.http.HttpUtil; +import cn.hutool.http.meta.Header; + +public class RedirectServerTest { + public static void main(final String[] args) { + HttpUtil.createServer(8888).addAction("/redirect1", (request, response) -> { + response.addHeader(Header.LOCATION.getValue(),"http://localhost:8888/redirect2"); + response.addHeader(Header.SET_COOKIE.getValue(),"redirect1=1; path=/; HttpOnly"); + response.send(301); + }).addAction("/redirect2", (request, response) -> { + response.addHeader(Header.LOCATION.getValue(),"http://localhost:8888/redirect3"); + response.addHeader(Header.SET_COOKIE.getValue(), "redirect2=2; path=/; HttpOnly"); + response.send(301); + }).addAction("/redirect3", (request, response) -> { + response.addHeader(Header.LOCATION.getValue(),"http://localhost:8888/redirect4"); + response.addHeader(Header.SET_COOKIE.getValue(),"redirect3=3; path=/; HttpOnly"); + response.send(301); + }).addAction("/redirect4", (request, response) -> { + final String cookie = request.getHeader(Header.COOKIE); + Console.log(cookie); + response.sendOk(); + }).start(); + } +}