diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java deleted file mode 100644 index 42bd9f4aa..000000000 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanPathOld.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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: - * https://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 org.dromara.hutool.core.bean; - -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.math.NumberUtil; -import org.dromara.hutool.core.text.CharUtil; -import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.text.split.SplitUtil; - -import java.io.Serializable; -import java.util.*; - -/** - * Bean路径表达式,用于获取多层嵌套Bean中的字段值或Bean对象
- * 根据给定的表达式,查找Bean中对应的属性值对象。 表达式分为两种: - *
    - *
  1. .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  2. - *
  3. []表达式,可以获取集合等对象中对应index的值
  4. - *
- *

- * 表达式栗子: - * - *

- * persion
- * persion.name
- * persons[3]
- * person.friends[5].name
- * ['person']['friends'][5]['name']
- * 
- * - * @author Looly - * @since 4.0.6 - */ -public class BeanPathOld implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * 表达式边界符号数组 - */ - private static final char[] EXP_CHARS = {CharUtil.DOT, CharUtil.BRACKET_START, CharUtil.BRACKET_END}; - - private boolean isStartWith = false; - protected List patternParts; - - /** - * 解析Bean路径表达式为Bean模式
- * Bean表达式,用于获取多层嵌套Bean中的字段值或Bean对象
- * 根据给定的表达式,查找Bean中对应的属性值对象。 表达式分为两种: - *
    - *
  1. .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  2. - *
  3. []表达式,可以获取集合等对象中对应index的值
  4. - *
- *

- * 表达式栗子: - * - *

-	 * persion
-	 * persion.name
-	 * persons[3]
-	 * person.friends[5].name
-	 * ['person']['friends'][5]['name']
-	 * 
- * - * @param expression 表达式 - * @return BeanPath - */ - public static BeanPathOld of(final String expression) { - return new BeanPathOld(expression); - } - - /** - * 构造 - * - * @param expression 表达式 - */ - public BeanPathOld(final String expression) { - init(expression); - } - - /** - * 获取表达式解析后的分段列表 - * - * @return 表达式分段列表 - */ - public List getPatternParts() { - return this.patternParts; - } - - /** - * 获取Bean中对应表达式的值 - * - * @param bean Bean对象或Map或List等 - * @return 值,如果对应值不存在,则返回null - */ - public Object get(final Object bean) { - return get(this.patternParts, bean); - } - - /** - * 设置表达式指定位置(或filed对应)的值
- * 若表达式指向一个List则设置其坐标对应位置的值,若指向Map则put对应key的值,Bean则设置字段的值
- * 注意: - * - *
-	 * 1. 如果为List,如果下标不大于List长度,则替换原有值,否则追加值
-	 * 2. 如果为数组,如果下标不大于数组长度,则替换原有值,否则追加值
-	 * 
- * - * @param bean Bean、Map或List - * @param value 值 - */ - public void set(final Object bean, final Object value) { - Objects.requireNonNull(bean); - - Object subBean = bean; - Object previousBean = null; - boolean isFirst = true; - String patternPart; - // 尝试找到倒数第二个子对象, 最终需要设置它的字段值 - final int length = patternParts.size() - 1; - - // 填充父字段缺失的对象 - for (int i = 0; i < length; i++) { - patternPart = patternParts.get(i); - // 保存当前操作的bean, 以便subBean不存在时, 可以用来填充缺失的子对象 - previousBean = subBean; - // 获取当前对象的子对象 - subBean = getFieldValue(subBean, patternPart); - if (null == subBean) { - // 支持表达式的第一个对象为Bean本身(若用户定义表达式$开头,则不做此操作) - if (isFirst && !this.isStartWith && BeanUtil.isMatchName(bean, patternPart, true)) { - subBean = bean; - isFirst = false; - } else { - // 填充缺失的子对象, 根据下一个表达式决定填充的值, 如果是整数(下标)则使用列表, 否则当做Map对象 - subBean = NumberUtil.isInteger(patternParts.get(i + 1)) ? new ArrayList<>() : new HashMap<>(); - BeanUtil.setFieldValue(previousBean, patternPart, subBean); - // 上面setFieldValue中有可能发生对象转换, 因此此处重新获取子对象 - // 欲知详情请自行阅读FieldUtil.setFieldValue(Object, Field, Object) - subBean = BeanUtil.getFieldValue(previousBean, patternPart); - } - } - } - - // 设置最终的(当前)字段值 - final Object newSubBean = BeanUtil.setFieldValue(subBean, patternParts.get(length), value); - if(newSubBean != subBean && null != previousBean){ - // 对象变更,重新加入 - BeanUtil.setFieldValue(previousBean, patternParts.get(length - 1), newSubBean); - } - } - - @Override - public String toString() { - return this.patternParts.toString(); - } - - //region Private Methods - - /** - * 获取Bean中对应表达式的值 - * - * @param patternParts 表达式分段列表 - * @param bean Bean对象或Map或List等 - * @return 值,如果对应值不存在,则返回null - */ - private Object get(final List patternParts, final Object bean) { - Object subBean = bean; - boolean isFirst = true; - for (final String patternPart : patternParts) { - subBean = getFieldValue(subBean, patternPart); - if (null == subBean) { - // 支持表达式的第一个对象为Bean本身(若用户定义表达式$开头,则不做此操作) - if (isFirst && !this.isStartWith && BeanUtil.isMatchName(bean, patternPart, true)) { - subBean = bean; - isFirst = false; - } else { - return null; - } - } - } - return subBean; - } - - @SuppressWarnings("unchecked") - private static Object getFieldValue(final Object bean, final String expression) { - if (StrUtil.isBlank(expression)) { - return null; - } - - if (StrUtil.contains(expression, CharUtil.COLON)) { - // [start:end:step] 模式 - final List parts = SplitUtil.splitTrim(expression, StrUtil.COLON); - final int start = Integer.parseInt(parts.get(0)); - final int end = Integer.parseInt(parts.get(1)); - int step = 1; - if (3 == parts.size()) { - step = Integer.parseInt(parts.get(2)); - } - if (bean instanceof Collection) { - return CollUtil.sub((Collection) bean, start, end, step); - } else if (ArrayUtil.isArray(bean)) { - return ArrayUtil.sub(bean, start, end, step); - } - } else if (StrUtil.contains(expression, ',')) { - // [num0,num1,num2...]模式或者['key0','key1']模式 - final List keys = SplitUtil.splitTrim(expression, StrUtil.COMMA); - if (bean instanceof Collection) { - return CollUtil.getAny((Collection) bean, Convert.convert(int[].class, keys)); - } else if (ArrayUtil.isArray(bean)) { - return ArrayUtil.getAny(bean, Convert.convert(int[].class, keys)); - } else { - final String[] unWrappedKeys = new String[keys.size()]; - for (int i = 0; i < unWrappedKeys.length; i++) { - unWrappedKeys[i] = StrUtil.unWrap(keys.get(i), CharUtil.SINGLE_QUOTE); - } - if (bean instanceof Map) { - // 只支持String为key的Map - return MapUtil.getAny((Map) bean, unWrappedKeys); - } else { - final Map map = BeanUtil.beanToMap(bean); - return MapUtil.getAny(map, unWrappedKeys); - } - } - } else { - // 数字或普通字符串 - return BeanUtil.getFieldValue(bean, expression); - } - - return null; - } - - /** - * 初始化 - * - * @param expression 表达式 - */ - private void init(final String expression) { - final List localPatternParts = new ArrayList<>(); - final int length = expression.length(); - - final StringBuilder builder = new StringBuilder(); - char c; - boolean isNumStart = false;// 下标标识符开始 - boolean isInWrap = false; //标识是否在引号内 - for (int i = 0; i < length; i++) { - c = expression.charAt(i); - if (0 == i && '$' == c) { - // 忽略开头的$符,表示当前对象 - isStartWith = true; - continue; - } - - if ('\'' == c) { - // 结束 - isInWrap = (!isInWrap); - continue; - } - - if (!isInWrap && ArrayUtil.contains(EXP_CHARS, c)) { - // 处理边界符号 - if (CharUtil.BRACKET_END == c) { - // 中括号(数字下标)结束 - if (!isNumStart) { - throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find ']' but no '[' !", expression, i)); - } - isNumStart = false; - // 中括号结束加入下标 - } else { - if (isNumStart) { - // 非结束中括号情况下发现起始中括号报错(中括号未关闭) - throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, i)); - } else if (CharUtil.BRACKET_START == c) { - // 数字下标开始 - isNumStart = true; - } - // 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY - } - if (builder.length() > 0) { - localPatternParts.add(builder.toString()); - } - builder.setLength(0); - } else { - // 非边界符号,追加字符 - builder.append(c); - } - } - - // 末尾边界符检查 - if (isNumStart) { - throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, length - 1)); - } else { - if (builder.length() > 0) { - localPatternParts.add(builder.toString()); - } - } - - // 不可变List - this.patternParts = ListUtil.view(localPatternParts); - } - //endregion -} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java index b0e6edb90..2c499aa20 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java @@ -16,6 +16,7 @@ import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.bean.copier.BeanCopier; import org.dromara.hutool.core.bean.copier.CopyOptions; import org.dromara.hutool.core.bean.copier.ValueProvider; +import org.dromara.hutool.core.bean.path.BeanPath; import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.set.SetUtil; @@ -67,7 +68,7 @@ public class BeanUtil { * @see #hasPublicField(Class) */ public static boolean isReadableBean(final Class clazz) { - if(null == clazz){ + if (null == clazz) { return false; } return hasGetter(clazz) || hasPublicField(clazz); @@ -87,7 +88,7 @@ public class BeanUtil { * @see #hasPublicField(Class) */ public static boolean isWritableBean(final Class clazz) { - if(null == clazz){ + if (null == clazz) { return false; } return hasSetter(clazz) || hasPublicField(clazz); @@ -244,7 +245,7 @@ public class BeanUtil { private static Map internalGetPropertyDescriptorMap(final Class clazz, final boolean ignoreCase) throws BeanException { final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); final Map map = ignoreCase ? new CaseInsensitiveMap<>(propertyDescriptors.length, 1f) - : new HashMap<>(propertyDescriptors.length, 1); + : new HashMap<>(propertyDescriptors.length, 1); for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) { map.put(propertyDescriptor.getName(), propertyDescriptor); @@ -355,7 +356,7 @@ public class BeanUtil { * @param bean Bean对象,支持Map、List、Collection、Array * @param expression 表达式,例如:person.friend[5].name * @return Bean属性值,bean为{@code null}或者express为空,返回{@code null} - * @see BeanPathOld#get(Object) + * @see BeanPath#getValue(Object) * @since 3.0.7 */ @SuppressWarnings("unchecked") @@ -363,7 +364,7 @@ public class BeanUtil { if (null == bean || StrUtil.isBlank(expression)) { return null; } - return (T) BeanPathOld.of(expression).get(bean); + return (T) BeanPath.of(expression).getValue(bean); } /** @@ -372,11 +373,11 @@ public class BeanUtil { * @param bean Bean对象,支持Map、List、Collection、Array * @param expression 表达式,例如:person.friend[5].name * @param value 属性值 - * @see BeanPathOld#get(Object) + * @see BeanPath#setValue(Object, Object) * @since 4.0.6 */ public static void setProperty(final Object bean, final String expression, final Object value) { - BeanPathOld.of(expression).set(bean, value); + BeanPath.of(expression).setValue(bean, value); } // --------------------------------------------------------------------------------------------- mapToBean @@ -625,9 +626,9 @@ public class BeanUtil { } return BeanCopier.of(bean, targetMap, - CopyOptions.of() - .setIgnoreNullValue(ignoreNullValue) - .setFieldEditor(keyEditor) + CopyOptions.of() + .setIgnoreNullValue(ignoreNullValue) + .setFieldEditor(keyEditor) ).copy(); } @@ -673,7 +674,7 @@ public class BeanUtil { if (null == source) { return null; } - if(RecordUtil.isRecord(tClass)){ + if (RecordUtil.isRecord(tClass)) { // issue#I7EO3U // 转换record时,ignoreProperties无效 return (T) RecordConverter.INSTANCE.convert(tClass, source); @@ -741,7 +742,7 @@ public class BeanUtil { } // issue#3091 - if(ClassUtil.isBasicType(targetType) || String.class == targetType){ + if (ClassUtil.isBasicType(targetType) || String.class == targetType) { return Convert.toList(targetType, collection); } @@ -864,7 +865,7 @@ public class BeanUtil { * @since 5.0.7 */ public static boolean isNotEmpty(final Object bean, final String... ignoreFieldNames) { - if(null == bean){ + if (null == bean) { return false; } @@ -887,7 +888,7 @@ public class BeanUtil { public static boolean hasNullField(final Object bean, final String... ignoreFieldNames) { return checkBean(bean, field -> (!ArrayUtil.contains(ignoreFieldNames, field.getName())) - && null == FieldUtil.getFieldValue(bean, field) + && null == FieldUtil.getFieldValue(bean, field) ); } @@ -913,11 +914,11 @@ public class BeanUtil { * 断言为{@code true} 时,返回{@code true}并不再检查后续字段;
* 断言为{@code false}时,继续检查后续字段 * - * @param bean Bean + * @param bean Bean * @param predicate 断言 * @return 是否触发断言为真 */ - public static boolean checkBean(final Object bean, final Predicate predicate){ + public static boolean checkBean(final Object bean, final Predicate predicate) { if (null == bean) { return true; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java index 7e5be41ec..37fa41ed9 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/DynaBean.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.bean; +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; @@ -37,7 +38,7 @@ public class DynaBean implements Cloneable, Serializable { private static final long serialVersionUID = 1L; private final Class beanClass; - private final Object bean; + private Object bean; /** * 创建一个DynaBean @@ -101,6 +102,13 @@ public class DynaBean implements Cloneable, Serializable { // 非数字,see pr#254@Gitee return (T) CollUtil.map((Collection) bean, (beanEle) -> DynaBean.of(beanEle).get(fieldName), false); } + } else if (ArrayUtil.isArray(bean)) { + try { + return ArrayUtil.get(bean, Integer.parseInt(fieldName)); + } catch (final NumberFormatException e) { + // 非数字,see pr#254@Gitee + return (T) ArrayUtil.map(bean, Object.class, (beanEle) -> DynaBean.of(beanEle).get(fieldName)); + } } else { final PropDesc prop = BeanUtil.getBeanDesc(beanClass).getProp(fieldName); if (null == prop) { @@ -148,21 +156,27 @@ public class DynaBean implements Cloneable, Serializable { * * @param fieldName 字段名 * @param value 字段值 + * @return this; * @throws BeanException 反射获取属性值或字段值导致的异常 */ @SuppressWarnings({"unchecked", "rawtypes"}) - public void set(final String fieldName, final Object value) throws BeanException { + public DynaBean set(final String fieldName, final Object value) throws BeanException { if (Map.class.isAssignableFrom(beanClass)) { ((Map) bean).put(fieldName, value); } else if (bean instanceof List) { ListUtil.setOrPadding((List) bean, Convert.toInt(fieldName), value); + } else if (ArrayUtil.isArray(bean)) { + // issue#3008,追加产生新数组,此处返回新数组 + this.bean = ArrayUtil.setOrPadding(bean, Convert.toInt(fieldName), value); } else { final PropDesc prop = BeanUtil.getBeanDesc(beanClass).getProp(fieldName); if (null == prop) { throw new BeanException("No public field or set method for '{}'", fieldName); } - prop.setValue(bean, value); + + prop.setValue(bean, value, false, false); } + return this; } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java index a9950aee4..18ac56efa 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java @@ -16,7 +16,10 @@ import org.dromara.hutool.core.annotation.AnnotationUtil; import org.dromara.hutool.core.annotation.PropIgnore; import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.func.LambdaUtil; -import org.dromara.hutool.core.reflect.*; +import org.dromara.hutool.core.reflect.FieldUtil; +import org.dromara.hutool.core.reflect.ModifierUtil; +import org.dromara.hutool.core.reflect.ReflectUtil; +import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.reflect.method.MethodUtil; import java.beans.Transient; diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java index cbd0adaaa..0eb5bfabc 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/BeanPath.java @@ -171,23 +171,29 @@ public class BeanPath implements Iterator { * * @param bean Bean对象 * @param value 设置的值 + * @return bean。如果在原Bean对象基础上设置值,返回原Bean,否则返回新的Bean */ - public void setValue(Object bean, final Object value) { - Object parentBean; - BeanPath beanPath = this; - while (beanPath.hasNext()) { - parentBean = bean; - bean = beanPath.node.getValue(bean); - if (null == bean) { - final BeanPath child = beanPath.next(); - bean = isListNode(child.node) ? new ArrayList<>() : new HashMap<>(); - beanPath.node.setValue(parentBean, bean); - // 如果自定义put方法修改了value,此处二次get避免丢失 - bean = beanPath.node.getValue(parentBean); - } - beanPath = beanPath.next(); + public Object setValue(final Object bean, final Object value) { + if (!hasNext()) { + // 根节点,直接赋值 + return this.node.setValue(bean, value); } - beanPath.node.setValue(bean, value); + + final BeanPath childBeanPath = next(); + Object subBean = this.node.getValue(bean); + if (null == subBean) { + subBean = isListNode(childBeanPath.node) ? new ArrayList<>() : new HashMap<>(); + this.node.setValue(bean, subBean); + // 如果自定义put方法修改了value,返回修改后的value,避免值丢失 + subBean = this.node.getValue(bean); + } + // 递归逐层查找子节点,赋值 + final Object newSubBean = childBeanPath.setValue(subBean, value); + if(newSubBean != subBean){ + //对于数组对象,set新值后,会返回新的数组,此时将新对象再加入父bean中,覆盖旧数组 + this.node.setValue(bean, newSubBean); + } + return bean; } @Override diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java index 56a4296e0..127f833d7 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/EmptyNode.java @@ -30,7 +30,8 @@ public class EmptyNode implements Node { } @Override - public void setValue(final Object bean, final Object value) { + public Object setValue(final Object bean, final Object value) { // do nothing + return bean; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java index e042e83ed..87ffbe283 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/ListNode.java @@ -65,7 +65,7 @@ public class ListNode implements Node{ } @Override - public void setValue(final Object bean, final Object value) { + public Object setValue(final Object bean, final Object value) { throw new UnsupportedOperationException("Can not set value to multi names."); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java index 954ed8214..0f6965ece 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/NameNode.java @@ -55,8 +55,8 @@ public class NameNode implements Node { } @Override - public void setValue(final Object bean, final Object value) { - DynaBean.of(bean).set(this.name, value); + public Object setValue(final Object bean, final Object value) { + return DynaBean.of(bean).set(this.name, value).getBean(); } @Override diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java index 86581480c..2627a604a 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/Node.java @@ -31,6 +31,7 @@ public interface Node { * * @param bean bean对象 * @param value 节点值 + * @return bean对象。如果在原Bean对象基础上设置值,返回原Bean,否则返回新的Bean */ - void setValue(Object bean, Object value); + Object setValue(Object bean, Object value); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java index ed0b7d843..d8f651700 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/path/node/RangeNode.java @@ -59,7 +59,7 @@ public class RangeNode implements Node { } @Override - public void setValue(final Object bean, final Object value) { + public Object setValue(final Object bean, final Object value) { throw new UnsupportedOperationException("Can not set value with step name."); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java index b0c7cdc1d..322e4e075 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/Dict.java @@ -12,26 +12,21 @@ package org.dromara.hutool.core.map; -import org.dromara.hutool.core.bean.BeanPathOld; import org.dromara.hutool.core.bean.BeanUtil; import org.dromara.hutool.core.bean.copier.CopyOptions; +import org.dromara.hutool.core.bean.path.BeanPath; import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.exception.CloneException; -import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.func.LambdaInfo; import org.dromara.hutool.core.func.LambdaUtil; import org.dromara.hutool.core.func.SerFunction; import org.dromara.hutool.core.func.SerSupplier; +import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.getter.TypeGetter; import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * 字典对象,扩充了LinkedHashMap中的方法 @@ -423,12 +418,12 @@ public class Dict extends CustomKeyMap implements TypeGetter 目标类型 * @param expression 表达式 * @return 对象 - * @see BeanPathOld#get(Object) + * @see BeanPath#getValue(Object) * @since 5.7.14 */ @SuppressWarnings("unchecked") public T getByPath(final String expression) { - return (T) BeanPathOld.of(expression).get(this); + return (T) BeanPath.of(expression).getValue(this); } /** @@ -453,7 +448,7 @@ public class Dict extends CustomKeyMap implements TypeGetter T getByPath(final String expression, final Type resultType) { diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java deleted file mode 100644 index 668c3cdc9..000000000 --- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanPathTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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: - * https://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 org.dromara.hutool.core.bean; - -import org.dromara.hutool.core.array.ArrayUtil; -import org.dromara.hutool.core.lang.test.bean.ExamInfoDict; -import org.dromara.hutool.core.lang.test.bean.UserInfoDict; -import org.dromara.hutool.core.map.Dict; -import lombok.Data; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * {@link BeanPathOld} 单元测试 - * - * @author looly - * - */ -public class BeanPathTest { - - Map tempMap; - - @BeforeEach - public void init() { - // ------------------------------------------------- 考试信息列表 - final ExamInfoDict examInfoDict = new ExamInfoDict(); - examInfoDict.setId(1); - examInfoDict.setExamType(0); - examInfoDict.setAnswerIs(1); - - final ExamInfoDict examInfoDict1 = new ExamInfoDict(); - examInfoDict1.setId(2); - examInfoDict1.setExamType(0); - examInfoDict1.setAnswerIs(0); - - final ExamInfoDict examInfoDict2 = new ExamInfoDict(); - examInfoDict2.setId(3); - examInfoDict2.setExamType(1); - examInfoDict2.setAnswerIs(0); - - final List examInfoDicts = new ArrayList<>(); - examInfoDicts.add(examInfoDict); - examInfoDicts.add(examInfoDict1); - examInfoDicts.add(examInfoDict2); - - // ------------------------------------------------- 用户信息 - final UserInfoDict userInfoDict = new UserInfoDict(); - userInfoDict.setId(1); - userInfoDict.setPhotoPath("yx.mm.com"); - userInfoDict.setRealName("张三"); - userInfoDict.setExamInfoDict(examInfoDicts); - - tempMap = new HashMap<>(); - tempMap.put("userInfo", userInfoDict); - tempMap.put("flag", 1); - } - - @Test - public void beanPathTest1() { - final BeanPathOld pattern = new BeanPathOld("userInfo.examInfoDict[0].id"); - Assertions.assertEquals("userInfo", pattern.patternParts.get(0)); - Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1)); - Assertions.assertEquals("0", pattern.patternParts.get(2)); - Assertions.assertEquals("id", pattern.patternParts.get(3)); - - } - - @Test - public void beanPathTest2() { - final BeanPathOld pattern = new BeanPathOld("[userInfo][examInfoDict][0][id]"); - Assertions.assertEquals("userInfo", pattern.patternParts.get(0)); - Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1)); - Assertions.assertEquals("0", pattern.patternParts.get(2)); - Assertions.assertEquals("id", pattern.patternParts.get(3)); - } - - @Test - public void beanPathTest3() { - final BeanPathOld pattern = new BeanPathOld("['userInfo']['examInfoDict'][0]['id']"); - Assertions.assertEquals("userInfo", pattern.patternParts.get(0)); - Assertions.assertEquals("examInfoDict", pattern.patternParts.get(1)); - Assertions.assertEquals("0", pattern.patternParts.get(2)); - Assertions.assertEquals("id", pattern.patternParts.get(3)); - } - - @Test - public void getTest() { - final BeanPathOld pattern = BeanPathOld.of("userInfo.examInfoDict[0].id"); - final Object result = pattern.get(tempMap); - Assertions.assertEquals(1, result); - } - - @Test - public void setTest() { - final BeanPathOld pattern = BeanPathOld.of("userInfo.examInfoDict[0].id"); - pattern.set(tempMap, 2); - final Object result = pattern.get(tempMap); - Assertions.assertEquals(2, result); - } - - @Test - public void getMapTest () { - final BeanPathOld pattern = BeanPathOld.of("userInfo[id, photoPath]"); - @SuppressWarnings("unchecked") - final Map result = (Map)pattern.get(tempMap); - Assertions.assertEquals(1, result.get("id")); - Assertions.assertEquals("yx.mm.com", result.get("photoPath")); - } - - @Test - public void getKeyWithDotTest () { - final Map dataMap = new HashMap<>(16); - dataMap.put("aa", "value0"); - dataMap.put("aa.bb.cc", "value111111");// key 是类名 格式 带 ' . ' - - final BeanPathOld pattern = BeanPathOld.of("'aa.bb.cc'"); - Assertions.assertEquals("value111111", pattern.get(dataMap)); - } - - @Test - public void compileTest(){ - final BeanPathOld of = BeanPathOld.of("'abc.dd'.ee.ff'.'"); - Assertions.assertEquals("abc.dd", of.getPatternParts().get(0)); - Assertions.assertEquals("ee", of.getPatternParts().get(1)); - Assertions.assertEquals("ff.", of.getPatternParts().get(2)); - } - - @Test - public void issue2362Test() { - final Map map = new HashMap<>(); - - BeanPathOld beanPath = BeanPathOld.of("list[0].name"); - beanPath.set(map, "张三"); - Assertions.assertEquals("{list=[{name=张三}]}", map.toString()); - - map.clear(); - beanPath = BeanPathOld.of("list[1].name"); - beanPath.set(map, "张三"); - Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString()); - - map.clear(); - beanPath = BeanPathOld.of("list[0].1.name"); - beanPath.set(map, "张三"); - Assertions.assertEquals("{list=[[null, {name=张三}]]}", map.toString()); - } - - @Test - public void putTest() { - final Map map = new HashMap<>(); - - final BeanPathOld beanPath = BeanPathOld.of("list[1].name"); - beanPath.set(map, "张三"); - Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString()); - } - - @Test - public void putByPathTest() { - final Dict dict = new Dict(); - BeanPathOld.of("aa.bb").set(dict, "BB"); - Assertions.assertEquals("{aa={bb=BB}}", dict.toString()); - } - - @Test - public void appendArrayTest(){ - // issue#3008@Github - final MyUser myUser = new MyUser(); - BeanPathOld.of("hobby[0]").set(myUser, "LOL"); - BeanPathOld.of("hobby[1]").set(myUser, "KFC"); - BeanPathOld.of("hobby[2]").set(myUser, "COFFE"); - - Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getHobby())); - } - - @Test - public void appendArrayTest2(){ - // issue#3008@Github - final MyUser2 myUser = new MyUser2(); - BeanPathOld.of("myUser.hobby[0]").set(myUser, "LOL"); - BeanPathOld.of("myUser.hobby[1]").set(myUser, "KFC"); - BeanPathOld.of("myUser.hobby[2]").set(myUser, "COFFE"); - - Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getMyUser().getHobby())); - } - - @Data - static class MyUser { - private String[] hobby; - } - - @Data - static class MyUser2 { - private MyUser myUser; - } -} diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java index 88b405f42..c2d41b979 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java @@ -12,10 +12,16 @@ package org.dromara.hutool.core.bean; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; import org.dromara.hutool.core.annotation.Alias; import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.bean.copier.CopyOptions; import org.dromara.hutool.core.bean.copier.ValueProvider; +import org.dromara.hutool.core.bean.path.BeanPath; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.map.MapBuilder; @@ -23,11 +29,6 @@ import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.thread.ThreadUtil; import org.dromara.hutool.core.util.ObjUtil; -import lombok.Data; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.experimental.Accessors; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -767,8 +768,8 @@ public class BeanUtilTest { testPojo.setTestPojo2List(new TestPojo2[]{testPojo2, testPojo3}); - final BeanPathOld beanPath = BeanPathOld.of("testPojo2List.age"); - final Object o = beanPath.get(testPojo); + final BeanPath beanPath = BeanPath.of("testPojo2List.age"); + final Object o = beanPath.getValue(testPojo); Assertions.assertEquals(Integer.valueOf(2), ArrayUtil.get(o, 0)); Assertions.assertEquals(Integer.valueOf(3), ArrayUtil.get(o, 1)); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java index 7e3105f3a..793088198 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/path/BeanPathGetOrSetValueTest.java @@ -12,8 +12,11 @@ package org.dromara.hutool.core.bean.path; +import lombok.Data; +import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.lang.test.bean.ExamInfoDict; import org.dromara.hutool.core.lang.test.bean.UserInfoDict; +import org.dromara.hutool.core.map.Dict; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -113,4 +116,52 @@ public class BeanPathGetOrSetValueTest { beanPath.setValue(map, "张三"); Assertions.assertEquals("{list=[[null, {name=张三}]]}", map.toString()); } + + @Test + public void putTest() { + final Map map = new HashMap<>(); + + final BeanPath beanPath = BeanPath.of("list[1].name"); + beanPath.setValue(map, "张三"); + Assertions.assertEquals("{list=[null, {name=张三}]}", map.toString()); + } + + @Test + public void putByPathTest() { + final Dict dict = new Dict(); + BeanPath.of("aa.bb").setValue(dict, "BB"); + Assertions.assertEquals("{aa={bb=BB}}", dict.toString()); + } + + @Test + public void appendArrayTest(){ + // issue#3008@Github + final MyUser myUser = new MyUser(); + BeanPath.of("hobby[0]").setValue(myUser, "LOL"); + BeanPath.of("hobby[1]").setValue(myUser, "KFC"); + BeanPath.of("hobby[2]").setValue(myUser, "COFFE"); + + Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getHobby())); + } + + @Test + public void appendArrayTest2(){ + // issue#3008@Github + final MyUser2 myUser = new MyUser2(); + BeanPath.of("myUser.hobby[0]").setValue(myUser, "LOL"); + BeanPath.of("myUser.hobby[1]").setValue(myUser, "KFC"); + BeanPath.of("myUser.hobby[2]").setValue(myUser, "COFFE"); + + Assertions.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getMyUser().getHobby())); + } + + @Data + static class MyUser { + private String[] hobby; + } + + @Data + static class MyUser2 { + private MyUser myUser; + } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/reflect/ReflectUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/ReflectUtilTest.java index 62828305c..1a8a43394 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/reflect/ReflectUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/ReflectUtilTest.java @@ -13,11 +13,6 @@ package org.dromara.hutool.core.reflect; import lombok.Data; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; /** * 反射工具类单元测试 diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java index 42d422a1f..0531e140b 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java @@ -12,7 +12,7 @@ package org.dromara.hutool.json; -import org.dromara.hutool.core.bean.BeanPathOld; +import org.dromara.hutool.core.bean.path.BeanPath; import org.dromara.hutool.core.convert.ConvertException; import org.dromara.hutool.core.convert.Converter; import org.dromara.hutool.core.lang.mutable.MutableEntry; @@ -64,11 +64,11 @@ public interface JSON extends Converter, Cloneable, Serializable { * * @param expression 表达式 * @return 对象 - * @see BeanPathOld#get(Object) + * @see BeanPath#getValue(Object) * @since 4.0.6 */ default Object getByPath(final String expression) { - return BeanPathOld.of(expression).get(this); + return BeanPath.of(expression).getValue(this); } /** @@ -93,7 +93,7 @@ public interface JSON extends Converter, Cloneable, Serializable { * @param value 值 */ default void putByPath(final String expression, final Object value) { - BeanPathOld.of(expression).set(this, value); + BeanPath.of(expression).setValue(this, value); } /** @@ -118,11 +118,11 @@ public interface JSON extends Converter, Cloneable, Serializable { * @param expression 表达式 * @param resultType 返回值类型 * @return 对象 - * @see BeanPathOld#get(Object) + * @see BeanPath#getValue(Object) * @since 4.0.6 */ @SuppressWarnings("unchecked") - default T getByPath(final String expression, final Type resultType){ + default T getByPath(final String expression, final Type resultType) { return (T) config().getConverter().convert(resultType, getByPath(expression)); } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java index d7b2dcbcd..cb3ebfa3e 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java @@ -340,7 +340,7 @@ public class JWT implements RegisteredPayload { * *

此方法会补充如下的header:

*
    - *
  • 当用户未定义"typ"时,赋默认值:"JWT"
  • + *
  • 当用户未定义"typ"时,不设置默认值
  • *
  • 当用户未定义"alg"时,根据传入的{@link JWTSigner}对象类型,赋值对应ID
  • *
* @@ -350,12 +350,6 @@ public class JWT implements RegisteredPayload { public String sign(final JWTSigner signer) { Assert.notNull(signer, () -> new JWTException("No Signer provided!")); - // 检查tye信息 - final String type = (String) this.header.getClaim(JWTHeader.TYPE); - if (StrUtil.isBlank(type)) { - this.header.setType("JWT"); - } - // 检查头信息中是否有算法信息 final String algorithm = (String) this.header.getClaim(JWTHeader.ALGORITHM); if (StrUtil.isBlank(algorithm)) { diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWTUtil.java b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWTUtil.java index 54a911e50..4e11c221a 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWTUtil.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWTUtil.java @@ -12,6 +12,7 @@ package org.dromara.hutool.json.jwt; +import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.json.jwt.signers.JWTSigner; import java.util.Map; @@ -29,7 +30,7 @@ public class JWTUtil { * @return JWT Token */ public static String createToken(final Map payload, final byte[] key) { - return createToken(null, payload, key); + return createToken(MapUtil.of(JWTHeader.TYPE, "JWT"), payload, key); } /** diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java index 2bc77bc5f..fb3cd7ab3 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java @@ -27,18 +27,19 @@ import java.util.*; public class JWTTest { @Test - public void createHs256Test(){ + public void createHs256Test() { final byte[] key = "1234567890".getBytes(); final JWT jwt = JWT.of() - .setPayload("sub", "1234567890") - .setPayload("name", "looly") - .setPayload("admin", true) - .setExpiresAt(DateUtil.parse("2022-01-01")) - .setKey(key); + .setHeader(JWTHeader.TYPE, "JWT") + .setPayload("sub", "1234567890") + .setPayload("name", "looly") + .setPayload("admin", true) + .setExpiresAt(DateUtil.parse("2022-01-01")) + .setKey(key); final String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." + - "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxvb2x5IiwiYWRtaW4iOnRydWUsImV4cCI6MTY0MDk2NjQwMH0." + - "bXlSnqVeJXWqUIt7HyEhgKNVlIPjkumHlAwFY-5YCtk"; + "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxvb2x5IiwiYWRtaW4iOnRydWUsImV4cCI6MTY0MDk2NjQwMH0." + + "bXlSnqVeJXWqUIt7HyEhgKNVlIPjkumHlAwFY-5YCtk"; final String token = jwt.sign(); Assertions.assertEquals(rightToken, token); @@ -47,10 +48,10 @@ public class JWTTest { } @Test - public void parseTest(){ + public void parseTest() { final String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." + - "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." + - "U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA"; + "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." + + "U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA"; final JWT jwt = JWT.of(rightToken); @@ -68,15 +69,16 @@ public class JWTTest { } @Test - public void createNoneTest(){ + public void createNoneTest() { final JWT jwt = JWT.of() - .setPayload("sub", "1234567890") - .setPayload("name", "looly") - .setPayload("admin", true) - .setSigner(JWTSignerUtil.none()); + .setHeader(JWTHeader.TYPE, "JWT") + .setPayload("sub", "1234567890") + .setPayload("name", "looly") + .setPayload("admin", true) + .setSigner(JWTSignerUtil.none()); final String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0." + - "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxvb2x5IiwiYWRtaW4iOnRydWV9."; + "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxvb2x5IiwiYWRtaW4iOnRydWV9."; final String token = jwt.sign(); Assertions.assertEquals(rightToken, token); @@ -88,8 +90,8 @@ public class JWTTest { * 必须定义签名器 */ @Test - public void needSignerTest(){ - Assertions.assertThrows(JWTException.class, ()->{ + public void needSignerTest() { + Assertions.assertThrows(JWTException.class, () -> { final JWT jwt = JWT.of() .setPayload("sub", "1234567890") .setPayload("name", "looly") @@ -100,10 +102,10 @@ public class JWTTest { } @Test - public void verifyTest(){ + public void verifyTest() { final String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." + - "eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ." + - "aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew"; + "eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ." + + "aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew"; final boolean verify = JWT.of(token).setKey(ByteUtil.toUtf8Bytes("123456")).verify(); Assertions.assertTrue(verify); @@ -114,6 +116,7 @@ public class JWTTest { private String name; private Integer age; } + @Test public void payloadTest() { @@ -130,6 +133,7 @@ public class JWTTest { map.put("test2", "2"); final Map payload = new HashMap() { private static final long serialVersionUID = 1L; + { put("username", username); put("bean", bean); @@ -161,11 +165,11 @@ public class JWTTest { } @Test() - public void getDateTest(){ + public void getDateTest() { final String token = JWT.of() - .setIssuedAt(DateUtil.parse("2022-02-02")) - .setKey("123456".getBytes()) - .sign(); + .setIssuedAt(DateUtil.parse("2022-02-02")) + .setKey("123456".getBytes()) + .sign(); // 签发时间早于被检查的时间 final Date date = JWT.of(token).getPayload().getClaimsJson().getDate(JWTPayload.ISSUED_AT); @@ -173,7 +177,7 @@ public class JWTTest { } @Test - public void issue2581Test(){ + public void issue2581Test() { final Map map = new HashMap<>(); map.put("test2", 22222222222222L); final JWTSigner jwtSigner = JWTSignerUtil.createSigner(AlgorithmUtil.getAlgorithm("HS256"), Base64.getDecoder().decode("abcdefghijklmn")); @@ -183,17 +187,17 @@ public class JWTTest { } @Test - public void getLongTest(){ + public void getLongTest() { final String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" - + ".eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJhZG1pbiIsImRldmljZSI6ImRlZmF1bHQtZGV2aWNlIiwiZWZmIjoxNjc4Mjg1NzEzOTM1LCJyblN0ciI6IkVuMTczWFhvWUNaaVZUWFNGOTNsN1pabGtOalNTd0pmIn0" - + ".wRe2soTaWYPhwcjxdzesDi1BgEm9D61K-mMT3fPc4YM"; + + ".eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJhZG1pbiIsImRldmljZSI6ImRlZmF1bHQtZGV2aWNlIiwiZWZmIjoxNjc4Mjg1NzEzOTM1LCJyblN0ciI6IkVuMTczWFhvWUNaaVZUWFNGOTNsN1pabGtOalNTd0pmIn0" + + ".wRe2soTaWYPhwcjxdzesDi1BgEm9D61K-mMT3fPc4YM"; final JWT jwt = JWTUtil.parseToken(rightToken); Assertions.assertEquals( - "{\"loginType\":\"login\",\"loginId\":\"admin\",\"device\":\"default-device\"," + - "\"eff\":1678285713935,\"rnStr\":\"En173XXoYCZiVTXSF93l7ZZlkNjSSwJf\"}", - jwt.getPayloads().toString()); + "{\"loginType\":\"login\",\"loginId\":\"admin\",\"device\":\"default-device\"," + + "\"eff\":1678285713935,\"rnStr\":\"En173XXoYCZiVTXSF93l7ZZlkNjSSwJf\"}", + jwt.getPayloads().toString()); Assertions.assertEquals(Long.valueOf(1678285713935L), jwt.getPayloads().getLong("eff")); } }