From 3a78b7d461a91dd2f83b5d62d6650cdf11430c5a Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 12 Jun 2024 00:34:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DVersionComparator=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E7=A9=BA=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/hutool/core/lang/Version.java | 7 ++- .../comparator/VersionComparatorTest.java | 49 ++++++++++++------- .../hutool/http/client/HeaderOperation.java | 39 +++++++++++++++ .../client/engine/jdk/JdkHttpConnection.java | 17 +++++++ 4 files changed, 93 insertions(+), 19 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Version.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Version.java index 1d60c9dbe..d8974abb0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Version.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Version.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.lang; +import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.comparator.CompareUtil; import org.dromara.hutool.core.text.CharUtil; @@ -61,7 +62,11 @@ public class Version implements Comparable, Serializable { Assert.notNull(v, "Null version string"); final int n = v.length(); if (n == 0){ - throw new IllegalArgumentException("Empty version string"); + this.version = v; + this.sequence = ListUtil.empty(); + this.pre = ListUtil.empty(); + this.build = ListUtil.empty(); + return; } this.version = v; this.sequence = new ArrayList<>(4); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/comparator/VersionComparatorTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/comparator/VersionComparatorTest.java index 0d3d8e5f1..35d29b3d4 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/comparator/VersionComparatorTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/comparator/VersionComparatorTest.java @@ -15,6 +15,8 @@ package org.dromara.hutool.core.comparator; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * 版本比较单元测试 * @@ -23,63 +25,74 @@ import org.junit.jupiter.api.Test; */ public class VersionComparatorTest { + @Test + public void compareEmptyTest() { + int compare = VersionComparator.INSTANCE.compare("", "1.12.1"); + assertTrue(compare < 0); + + compare = VersionComparator.INSTANCE.compare("", null); + assertTrue(compare > 0); + compare = VersionComparator.INSTANCE.compare(null, ""); + assertTrue(compare < 0); + } + @Test public void versionComparatorTest1() { int compare = VersionComparator.INSTANCE.compare("1.2.1", "1.12.1"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("1.12.1", "1.2.1"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); } @Test public void versionComparatorTest2() { int compare = VersionComparator.INSTANCE.compare("1.12.1", "1.12.1c"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.12.1"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); } @Test public void versionComparatorTest3() { int compare = VersionComparator.INSTANCE.compare(null, "1.12.1c"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("1.12.1c", null); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); } @Test public void versionComparatorTest4() { int compare = VersionComparator.INSTANCE.compare("1.13.0", "1.12.1c"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.13.0"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); } @Test public void versionComparatorTest5() { int compare = VersionComparator.INSTANCE.compare("V1.2", "V1.1"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("V1.1", "V1.2"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); } @Test public void versionComparatorTes6() { int compare = VersionComparator.INSTANCE.compare("V0.0.20170102", "V0.0.20170101"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("V0.0.20170101", "V0.0.20170102"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); } @Test @@ -92,11 +105,11 @@ public class VersionComparatorTest { @Test public void versionComparatorTest7() { int compare = VersionComparator.INSTANCE.compare("1.12.2", "1.12.1c"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); // 自反测试 compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.12.2"); - Assertions.assertTrue(compare < 0); + assertTrue(compare < 0); } @Test @@ -109,16 +122,16 @@ public class VersionComparatorTest { void I8Z3VETest() { // 传递性测试 int compare = VersionComparator.INSTANCE.compare("260", "a-34"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); compare = VersionComparator.INSTANCE.compare("a-34", "a-3"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); compare = VersionComparator.INSTANCE.compare("260", "a-3"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); } @Test void startWithNoneNumberTest() { final int compare = VersionComparator.INSTANCE.compare("V1", "A1"); - Assertions.assertTrue(compare > 0); + assertTrue(compare > 0); } } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/HeaderOperation.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/HeaderOperation.java index 67d9ee5f1..39b7f3d00 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/HeaderOperation.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/HeaderOperation.java @@ -15,6 +15,7 @@ package org.dromara.hutool.http.client; import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.http.HttpUtil; @@ -173,6 +174,44 @@ public interface HeaderOperation> { return (T) this; } + /** + * 获取内容长度,以下情况长度无效: + *
    + *
  • Transfer-Encoding: Chunked
  • + *
  • Content-Encoding: XXX
  • + *
+ * + * @return 长度,-1表示服务端未返回或长度无效 + * @since 5.7.9 + */ + default long contentLength() { + long contentLength = Convert.toLong(header(HeaderName.CONTENT_LENGTH), -1L); + if (contentLength > 0 && (isChunked() || StrUtil.isNotBlank(contentEncoding()))) { + //按照HTTP协议规范,在 Transfer-Encoding和Content-Encoding设置后 Content-Length 无效。 + contentLength = -1; + } + return contentLength; + } + + /** + * 是否为Transfer-Encoding:Chunked的内容 + * + * @return 是否为Transfer-Encoding:Chunked的内容 + * @since 4.6.2 + */ + default boolean isChunked() { + return "Chunked".equalsIgnoreCase(header(HeaderName.TRANSFER_ENCODING)); + } + + /** + * 获取内容编码 + * + * @return String + */ + default String contentEncoding() { + return header(HeaderName.CONTENT_ENCODING); + } + // endregion ----------------------------------------------------------- headers // region ----------------------------------------------------------- auth diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkHttpConnection.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkHttpConnection.java index 6d8f05f5b..f09881cce 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkHttpConnection.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkHttpConnection.java @@ -203,6 +203,7 @@ public class JdkHttpConnection implements HeaderOperation, Cl * @param timeout 超时时间 * @return this */ + @SuppressWarnings("resource") public JdkHttpConnection setConnectionAndReadTimeout(final int timeout) { setConnectTimeout(timeout); setReadTimeout(timeout); @@ -233,6 +234,22 @@ public class JdkHttpConnection implements HeaderOperation, Cl return this; } + /** + * 设置固定长度的流模式,会设置HTTP请求头中的Content-Length字段,告知服务器整个请求体的精确字节大小。
+ * 这在上传文件或大数据量时非常有用,因为它允许服务器准确地知道何时接收完所有的请求数据,而不需要依赖于连接的关闭来判断数据传输的结束。 + * + * @param contentLength 请求体的长度。如果内容长度大于0,则启用固定长度流模式。 + * @return this + */ + public JdkHttpConnection setFixedLengthStreamingMode(final long contentLength) { + // 当内容长度大于0时,启用固定长度流模式 + if (contentLength > 0) { + conn.setFixedLengthStreamingMode(contentLength); + } + // 返回当前实例,支持方法链式调用 + return this; + } + /** * 采用流方式上传数据,无需本地缓存数据。
* HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。