From 511f688d1eb9a0ec6d4a337f4f60afc7bd20499c Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 11 Mar 2021 17:10:02 +0800 Subject: [PATCH] fix bug#I3AXIJ --- CHANGELOG.md | 4 ++- .../java/cn/hutool/core/bean/BeanDesc.java | 30 ++++++++++++------- .../cn/hutool/core/bean/BeanDescTest.java | 28 ++++++++--------- .../main/java/cn/hutool/json/JSONUtil.java | 29 ++++++++++++++++++ 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec106e7fa..c4b37e6d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.6.0 (2021-03-10) +# 5.6.0 (2021-03-11) ### 新特性 * 【poi 】 重要:不再兼容POI-3.x,增加兼容POI-5.x(issue#I35J6B@Gitee) @@ -15,10 +15,12 @@ * 【core 】 NumberUtil增加factorial针对BigInterger方法(issue#1379@Github) * 【core 】 TreeNode增加equals方法(issue#1467@Github) * 【core 】 增加汉字转阿拉伯数字Convert.chineseToNumber(pr#1469@Github) +* 【json 】 JSONUtil增加getByPath方法支持默认值(issue#1470@Github) ### Bug修复 * 【socket 】 修复Client创建失败资源未释放问题。 * 【core 】 修复DataSizeUtil中EB单位错误问题(issue#I39O7I@Gitee) +* 【core 】 修复BeanDesc.isMatchSetter的ignoreCase未使用问题(issue#I3AXIJ@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java index 10e24af25..a13e0b0c8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java @@ -249,12 +249,14 @@ public class BeanDesc implements Serializable { * @return 是否匹配 */ private boolean isMatchGetter(String methodName, String fieldName, boolean isBooleanField, boolean ignoreCase) { - // 全部转为小写,忽略大小写比较 + final String handledFieldName; if (ignoreCase) { + // 全部转为小写,忽略大小写比较 methodName = methodName.toLowerCase(); - fieldName = fieldName.toLowerCase(); + handledFieldName = fieldName.toLowerCase(); + fieldName = handledFieldName; } else { - fieldName = StrUtil.upperFirst(fieldName); + handledFieldName = StrUtil.upperFirst(fieldName); } if (false == methodName.startsWith("get") && false == methodName.startsWith("is")) { @@ -271,12 +273,12 @@ public class BeanDesc implements Serializable { if (fieldName.startsWith("is")) { // 字段已经是is开头 if (methodName.equals(fieldName) // isName -》 isName - || methodName.equals("get" + fieldName)// isName -》 getIsName - || methodName.equals("is" + fieldName)// isName -》 isIsName + || methodName.equals("get" + handledFieldName)// isName -》 getIsName + || methodName.equals("is" + handledFieldName)// isName -》 isIsName ) { return true; } - } else if (methodName.equals("is" + fieldName)) { + } else if (methodName.equals("is" + handledFieldName)) { // 字段非is开头, name -》 isName return true; } @@ -304,9 +306,15 @@ public class BeanDesc implements Serializable { * @return 是否匹配 */ private boolean isMatchSetter(String methodName, String fieldName, boolean isBooleanField, boolean ignoreCase) { - // 全部转为小写,忽略大小写比较 - methodName = methodName.toLowerCase(); - fieldName = fieldName.toLowerCase(); + final String handledFieldName; + if (ignoreCase) { + // 全部转为小写,忽略大小写比较 + methodName = methodName.toLowerCase(); + handledFieldName = fieldName.toLowerCase(); + fieldName = handledFieldName; + } else { + handledFieldName = StrUtil.upperFirst(fieldName); + } // 非标准Setter方法跳过 if (false == methodName.startsWith("set")) { @@ -314,7 +322,7 @@ public class BeanDesc implements Serializable { } // 针对Boolean类型特殊检查 - if (isBooleanField && fieldName.startsWith("is")) { + if (isBooleanField && handledFieldName.startsWith("is")) { // 字段是is开头 if (methodName.equals("set" + StrUtil.removePrefix(fieldName, "is"))// isName -》 setName || methodName.equals("set" + fieldName)// isName -》 setIsName @@ -327,4 +335,4 @@ public class BeanDesc implements Serializable { return methodName.equals("set" + fieldName); } // ------------------------------------------------------------------------------------------------------ Private method end -} \ No newline at end of file +} diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanDescTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanDescTest.java index 6e416b514..1f0a93e2d 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanDescTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanDescTest.java @@ -5,7 +5,7 @@ import org.junit.Test; /** * {@link BeanDesc} 单元测试类 - * + * * @author looly * */ @@ -20,48 +20,48 @@ public class BeanDescTest { Assert.assertEquals("getAge", desc.getGetter("age").getName()); Assert.assertEquals("setAge", desc.getSetter("age").getName()); Assert.assertEquals(1, desc.getSetter("age").getParameterTypes().length); - Assert.assertEquals(int.class, desc.getSetter("age").getParameterTypes()[0]); - + Assert.assertSame(int.class, desc.getSetter("age").getParameterTypes()[0]); + } - + @Test public void propDescTes2() { BeanDesc desc = BeanUtil.getBeanDesc(User.class); - + PropDesc prop = desc.getProp("name"); Assert.assertEquals("name", prop.getFieldName()); Assert.assertEquals("getName", prop.getGetter().getName()); Assert.assertEquals("setName", prop.getSetter().getName()); Assert.assertEquals(1, prop.getSetter().getParameterTypes().length); - Assert.assertEquals(String.class, prop.getSetter().getParameterTypes()[0]); + Assert.assertSame(String.class, prop.getSetter().getParameterTypes()[0]); } - + @Test public void propDescOfBooleanTest() { BeanDesc desc = BeanUtil.getBeanDesc(User.class); - + Assert.assertEquals("isAdmin", desc.getGetter("isAdmin").getName()); Assert.assertEquals("setAdmin", desc.getSetter("isAdmin").getName()); Assert.assertEquals("isGender", desc.getGetter("gender").getName()); Assert.assertEquals("setGender", desc.getSetter("gender").getName()); } - + @Test public void propDescOfBooleanTest2() { BeanDesc desc = BeanUtil.getBeanDesc(User.class); - + Assert.assertEquals("isIsSuper", desc.getGetter("isSuper").getName()); Assert.assertEquals("setIsSuper", desc.getSetter("isSuper").getName()); } - + @Test public void getSetTest() { BeanDesc desc = BeanUtil.getBeanDesc(User.class); - + User user = new User(); desc.getProp("name").setValue(user, "张三"); Assert.assertEquals("张三", user.getName()); - + Object value = desc.getProp("name").getValue(user); Assert.assertEquals("张三", value); } @@ -101,7 +101,7 @@ public class BeanDescTest { public void setAdmin(boolean isAdmin) { this.isAdmin = isAdmin; } - + public boolean isIsSuper() { return isSuper; } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java index e57756e69..618150fcc 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -546,6 +546,35 @@ public class JSONUtil { return (null == json || StrUtil.isBlank(expression)) ? null : json.getByPath(expression); } + /** + * 通过表达式获取JSON中嵌套的对象
+ *
    + *
  1. .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  2. + *
  3. []表达式,可以获取集合等对象中对应index的值
  4. + *
+ *

+ * 表达式栗子: + * + *

+	 * persion
+	 * persion.name
+	 * persons[3]
+	 * person.friends[5].name
+	 * 
+ * + * @param 值类型 + * @param json {@link JSON} + * @param expression 表达式 + * @param defaultValue 默认值 + * @return 对象 + * @see JSON#getByPath(String) + * @since 5.6.0 + */ + @SuppressWarnings("unchecked") + public static T getByPath(JSON json, String expression, T defaultValue) { + return (T) ObjectUtil.defaultIfNull(getByPath(json, expression), defaultValue); + } + /** * 设置表达式指定位置(或filed对应)的值
* 若表达式指向一个JSONArray则设置其坐标对应位置的值,若指向JSONObject则put对应key的值