diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8226f09..90de4a767 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * 【db 】 修复insertOrUpdate更新中条件字段没有移除问题(issue#I6W91Z@Gitee) * 【core 】 修复VIN(车架号)正则问题(pr#3078@Github) * 【core 】 修复HtmlUtil的removeHtmlAttr方法匹配问题(issue#I6YNTF@Gitee) +* 【core 】 修复JSONUtil.toBean目标存在Map字段无序问题(issue#I6YN2A@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.18 (2023-04-16) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java index b99a5d6b9..72b4c32b7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java @@ -8,8 +8,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.TypeUtil; import java.lang.reflect.Type; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * {@link Map} 转换器 @@ -65,14 +64,21 @@ public class MapConverter extends AbstractConverter> { return (Map) value; } } - map = MapUtil.createMap(TypeUtil.getClass(this.mapType)); + + final Class mapClass = TypeUtil.getClass(this.mapType); + if (null == mapClass || mapClass.isAssignableFrom(AbstractMap.class)) { + // issue#I6YN2A,默认有序 + map = new LinkedHashMap<>(); + } else{ + map = MapUtil.createMap(mapClass); + } convertMapToMap((Map) value, map); } else if (BeanUtil.isBean(value.getClass())) { map = BeanUtil.beanToMap(value); // 二次转换,转换键值类型 map = convertInternal(map); } else { - throw new UnsupportedOperationException(StrUtil.format("Unsupport toMap value type: {}", value.getClass().getName())); + throw new UnsupportedOperationException(StrUtil.format("Unsupported toMap value type: {}", value.getClass().getName())); } return map; } diff --git a/hutool-json/src/test/java/Issue3051Test.java b/hutool-json/src/test/java/cn/hutool/json/Issue3051Test.java similarity index 95% rename from hutool-json/src/test/java/Issue3051Test.java rename to hutool-json/src/test/java/cn/hutool/json/Issue3051Test.java index f37430128..aa06ee69f 100644 --- a/hutool-json/src/test/java/Issue3051Test.java +++ b/hutool-json/src/test/java/cn/hutool/json/Issue3051Test.java @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. */ -import cn.hutool.json.JSONConfig; +package cn.hutool.json;import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.Data; diff --git a/hutool-json/src/test/java/cn/hutool/json/IssueI6YN2ATest.java b/hutool-json/src/test/java/cn/hutool/json/IssueI6YN2ATest.java new file mode 100755 index 000000000..633408e8c --- /dev/null +++ b/hutool-json/src/test/java/cn/hutool/json/IssueI6YN2ATest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package cn.hutool.json; + +import cn.hutool.core.lang.Console; +import cn.hutool.core.lang.TypeReference; +import lombok.Data; +import org.junit.Assert; +import org.junit.Test; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class IssueI6YN2ATest { + + @Test + public void toBeanTest() { + final String str = "{\"conditions\":{\"user\":\"test\",\"sex\":\"男\"},\"headers\":{\"name\":\"姓名\",\"age\":\"年龄\",\"email\":\"邮箱\",\"number\":\"号码\",\"pwd\":\"密码\"}}"; + final JSONObject jsonObject = JSONUtil.parseObj(str); + + final PageQuery bean = jsonObject.toBean(PageQuery.class); + Assert.assertEquals("{name=姓名, age=年龄, email=邮箱, number=号码, pwd=密码}", bean.headers.toString()); + } + + @Data + public static class PageQuery { + /** + * 要导出的字段 + */ + private Map headers = new LinkedHashMap<>(); + private T conditions; + + @Override + public String toString() { + return JSONUtil.parse(this, JSONConfig.create()).toJSONString(0); + } + } + + @Data + public static class User { + private String name; + private String sex; + } +}