Looly 5 年 前
コミット
aff16c283c

+ 1 - 0
CHANGELOG.md

@@ -10,6 +10,7 @@
 
 ### Bug修复
 * 【core   】     修复在Linux下FileUtil.move失败问题(issue#I254Y3@Gitee)
+* 【http   】     修复UrlUtil和UrlBuilder中多个/被替换问题(issue#I25MZL@Gitee)
 
 -------------------------------------------------------------------------------------------------------------
 

+ 23 - 27
hutool-core/src/main/java/cn/hutool/core/net/url/UrlPath.java

@@ -1,6 +1,7 @@
 package cn.hutool.core.net.url;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.CharUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.URLUtil;
@@ -8,7 +9,6 @@ import cn.hutool.core.util.URLUtil;
 import java.nio.charset.Charset;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.StringTokenizer;
 
 /**
  * URL中Path部分的封装
@@ -17,6 +17,7 @@ import java.util.StringTokenizer;
  * @since 5.3.1
  */
 public class UrlPath {
+
 	private List<String> segments;
 	private boolean withEngTag;
 
@@ -25,7 +26,7 @@ public class UrlPath {
 	 *
 	 * @param pathStr 初始化的路径字符串
 	 * @param charset decode用的编码,null表示不做decode
-	 * @return {@link UrlPath}
+	 * @return UrlPath
 	 */
 	public static UrlPath of(String pathStr, Charset charset) {
 		final UrlPath urlPath = new UrlPath();
@@ -73,7 +74,7 @@ public class UrlPath {
 	 * @return this
 	 */
 	public UrlPath add(CharSequence segment) {
-		add(segment, false);
+		addInternal(fixPath(segment), false);
 		return this;
 	}
 
@@ -84,14 +85,14 @@ public class UrlPath {
 	 * @return this
 	 */
 	public UrlPath addBefore(CharSequence segment) {
-		add(segment, true);
+		addInternal(fixPath(segment), true);
 		return this;
 	}
 
 	/**
 	 * 解析path
 	 *
-	 * @param path    路径,类似于aaa/bb/ccc
+	 * @param path    路径,类似于aaa/bb/ccc或/aaa/bbb/ccc
 	 * @param charset decode编码,null表示不解码
 	 * @return this
 	 */
@@ -99,16 +100,15 @@ public class UrlPath {
 		UrlPath urlPath = new UrlPath();
 
 		if (StrUtil.isNotEmpty(path)) {
-			path = path.trim();
-
 			// 原URL中以/结尾,则这个规则需保留,issue#I1G44J@Gitee
 			if(StrUtil.endWith(path, CharUtil.SLASH)){
 				this.withEngTag = true;
 			}
 
-			final StringTokenizer tokenizer = new StringTokenizer(path, "/");
-			while (tokenizer.hasMoreTokens()) {
-				add(URLUtil.decode(tokenizer.nextToken(), charset));
+			path = fixPath(path);
+			final List<String> split = StrUtil.split(path, '/');
+			for (String seg : split) {
+				addInternal(URLUtil.decode(seg, charset), false);
 			}
 		}
 
@@ -147,16 +147,12 @@ public class UrlPath {
 	 * @param segment 节点
 	 * @param before  是否在前面添加
 	 */
-	private void add(CharSequence segment, boolean before) {
-		final String seg = fixSegment(segment);
-		if (null == seg) {
-			return;
-		}
-
-
+	private void addInternal(CharSequence segment, boolean before) {
 		if (this.segments == null) {
 			this.segments = new LinkedList<>();
 		}
+
+		final String seg = StrUtil.str(segment);
 		if (before) {
 			this.segments.add(0, seg);
 		} else {
@@ -165,20 +161,20 @@ public class UrlPath {
 	}
 
 	/**
-	 * 修正节点,包括去掉前后的/,去掉空白符
+	 * 修正路径,包括去掉前后的/,去掉空白符
 	 *
-	 * @param segment 节点
-	 * @return 修正后的节点
+	 * @param path 节点或路径path
+	 * @return 修正后的路径
 	 */
-	private static String fixSegment(CharSequence segment) {
-		if (StrUtil.isEmpty(segment) || "/".contentEquals(segment)) {
-			return null;
+	private static String fixPath(CharSequence path) {
+		Assert.notNull(path, "Path segment must be not null!");
+		if ("/".contentEquals(path)) {
+			return StrUtil.EMPTY;
 		}
 
-		String segmentStr = StrUtil.str(segment);
-		segmentStr = StrUtil.trim(segmentStr);
-		segmentStr = StrUtil.removePrefix(segmentStr, "/");
-		segmentStr = StrUtil.removeSuffix(segmentStr, "/");
+		String segmentStr = StrUtil.trim(path);
+		segmentStr = StrUtil.removePrefix(segmentStr, StrUtil.SLASH);
+		segmentStr = StrUtil.removeSuffix(segmentStr, StrUtil.SLASH);
 		segmentStr = StrUtil.trim(segmentStr);
 		return segmentStr;
 	}

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

@@ -1972,7 +1972,7 @@ public class NumberUtil {
 	 * @param number A Number
 	 * @return A String.
 	 */
-	public static String toStr(Number number) {
+		public static String toStr(Number number) {
 		Assert.notNull(number, "Number is null !");
 
 		// BigDecimal单独处理,使用非科学计数法

+ 3 - 1
hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java

@@ -707,7 +707,9 @@ public class URLUtil {
 			//noinspection ConstantConditions
 			body = body.replaceAll("^[\\\\/]+", StrUtil.EMPTY);
 			// 替换多个\或/为单个/
-			body = body.replace("\\", "/").replaceAll("//+", "/");
+			body = body.replace("\\", "/");
+			//issue#I25MZL,双斜杠在URL中是允许存在的,不做替换
+			//.replaceAll("//+", "/");
 		}
 
 		final int pathSepIndex = StrUtil.indexOf(body, '/');

+ 7 - 0
hutool-core/src/test/java/cn/hutool/core/net/UrlBuilderTest.java

@@ -210,4 +210,11 @@ public class UrlBuilderTest {
 		final UrlBuilder urlBuilder = UrlBuilder.ofHttp("http://xtbgyy.digitalgd.com.cn/ebus/../../..", CharsetUtil.CHARSET_UTF_8);
 		Assert.assertEquals("http://xtbgyy.digitalgd.com.cn/ebus/../../..", urlBuilder.toString());
 	}
+
+	@Test
+	public void multiSlashTest(){
+		//issue#I25MZL,某些URL中有多个斜杠,此为合法路径
+		final UrlBuilder urlBuilder = UrlBuilder.ofHttp("https://hutool.cn//file/test.jpg", CharsetUtil.CHARSET_UTF_8);
+		Assert.assertEquals("https://hutool.cn//file/test.jpg", urlBuilder.toString());
+	}
 }

+ 9 - 0
hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java

@@ -526,4 +526,13 @@ public class JSONObjectTest {
 		// 集合类不支持转为JSONObject
 		new JSONObject(new JSONArray(), JSONConfig.create());
 	}
+
+	@Test
+	public void floatTest(){
+		Map<String, Object> map = new HashMap<>();
+		map.put("c", 2.0F);
+
+		final String s = JSONUtil.toJsonStr(map);
+		Console.log(s);
+	}
 }