fix: 修复数组和集合的 allMatch 校验方法对空值的处理

- 在 `ArrayPropertyValidator` 的 `allMatch` 方法中添加空值检查,当数组为空或 `null` 时直接返回
- 在 `CollectionPropertyValidator` 的 `allMatch` 方法中添加空值检查,当集合为空或 `null` 时直接返回
- 更新相关方法的文档注释,说明 `null` 值被视为通过校验
- 添加针对空数组、空集合和 `null` 值的测试用例
- 确保只有非空情况才会执行元素匹配校验逻辑
This commit is contained in:
2026-05-27 11:15:32 +08:00
parent e22a95861d
commit fdabd29347
4 changed files with 93 additions and 20 deletions

View File

@@ -151,11 +151,17 @@ public class ArrayPropertyValidator<T, E>
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当数组为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param condition 校验条件
* @return 当前校验器实例,用于链式调用
*/
public final ArrayPropertyValidator<T, E> allMatch(final Predicate<E> condition) {
return withRule(c -> {
if (ArrayTools.isEmpty(c)) {
return;
}
for (E element : c) {
if (!condition.test(element)) {
throw ValidationException.withMessage("All elements must match the condition.");
@@ -167,6 +173,9 @@ public class ArrayPropertyValidator<T, E>
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当数组为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param condition 校验条件
* @param errorMessage 异常信息
* @return 当前校验器实例,用于链式调用
@@ -174,6 +183,9 @@ public class ArrayPropertyValidator<T, E>
public final ArrayPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final String errorMessage) {
return withRule(c -> {
if (ArrayTools.isEmpty(c)) {
return;
}
for (E element : c) {
if (!condition.test(element)) {
throw ValidationException.withMessage(errorMessage);
@@ -185,6 +197,9 @@ public class ArrayPropertyValidator<T, E>
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当数组为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param <X> 自定义异常类型
* @param condition 校验条件
* @param exceptionSupplier 自定义异常
@@ -193,6 +208,9 @@ public class ArrayPropertyValidator<T, E>
public final <X extends RuntimeException> ArrayPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final Supplier<X> exceptionSupplier) {
return withRule(c -> {
if (ArrayTools.isEmpty(c)) {
return;
}
for (E element : c) {
if (!condition.test(element)) {
throw exceptionSupplier.get();
@@ -204,6 +222,9 @@ public class ArrayPropertyValidator<T, E>
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当数组为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param <X> 自定义异常类型
* @param condition 校验条件
* @param exceptionFunction 自定义异常
@@ -212,6 +233,9 @@ public class ArrayPropertyValidator<T, E>
public final <X extends RuntimeException> ArrayPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final Function<E, X> exceptionFunction) {
return withRule(c -> {
if (ArrayTools.isEmpty(c)) {
return;
}
for (E element : c) {
if (!condition.test(element)) {
throw exceptionFunction.apply(element);

View File

@@ -151,36 +151,56 @@ public class CollectionPropertyValidator<T, E>
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当集合为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param condition 校验条件
* @return 当前校验器实例,用于链式调用
*/
public final CollectionPropertyValidator<T, E> allMatch(
final Predicate<E> condition) {
return withRule(c -> c.forEach(element -> {
if (!condition.test(element)) {
throw ValidationException.withMessage("All elements must match the condition.");
return withRule(c -> {
if (CollectionTools.isEmpty(c)) {
return;
}
}));
c.forEach(element -> {
if (!condition.test(element)) {
throw ValidationException.withMessage("All elements must match the condition.");
}
});
});
}
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当集合为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param condition 校验条件
* @param errorMessage 异常信息
* @return 当前校验器实例,用于链式调用
*/
public final CollectionPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final String errorMessage) {
return withRule(c -> c.forEach(element -> {
if (!condition.test(element)) {
throw ValidationException.withMessage(errorMessage);
return withRule(c -> {
if (CollectionTools.isEmpty(c)) {
return;
}
}));
c.forEach(element -> {
if (!condition.test(element)) {
throw ValidationException.withMessage(errorMessage);
}
});
});
}
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当集合为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param <X> 自定义异常类型
* @param condition 校验条件
* @param exceptionSupplier 自定义异常
@@ -188,16 +208,24 @@ public class CollectionPropertyValidator<T, E>
*/
public final <X extends RuntimeException> CollectionPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final Supplier<X> exceptionSupplier) {
return withRule(c -> c.forEach(element -> {
if (!condition.test(element)) {
throw exceptionSupplier.get();
return withRule(c -> {
if (CollectionTools.isEmpty(c)) {
return;
}
}));
c.forEach(element -> {
if (!condition.test(element)) {
throw exceptionSupplier.get();
}
});
});
}
/**
* 添加一条校验属性的规则,校验是否所有元素都满足指定条件
*
* <p>
* 当集合为 {@code null} 时,视为通过。如果需要校验值不为 {@code null},请使用 {@link #notNull()} 方法。
*
* @param <X> 自定义异常类型
* @param condition 校验条件
* @param exceptionFunction 自定义异常
@@ -205,11 +233,16 @@ public class CollectionPropertyValidator<T, E>
*/
public final <X extends RuntimeException> CollectionPropertyValidator<T, E> allMatch(
final Predicate<E> condition, final Function<E, X> exceptionFunction) {
return withRule(c -> c.forEach(element -> {
if (!condition.test(element)) {
throw exceptionFunction.apply(element);
return withRule(c -> {
if (CollectionTools.isEmpty(c)) {
return;
}
}));
c.forEach(element -> {
if (!condition.test(element)) {
throw exceptionFunction.apply(element);
}
});
});
}
// ================================

View File

@@ -293,8 +293,18 @@ public class ArrayPropertyValidatorTests {
}
};
ExampleCommand command = exampleCommandWithStringArrayProperty(new String[] { "1234", "12345", "123456" });
assertDoesNotThrow(() -> validator.validate(command));
{
ExampleCommand command = exampleCommandWithStringArrayProperty(new String[] { "1234", "12345", "123456" });
assertDoesNotThrow(() -> validator.validate(command));
}
{
ExampleCommand command = exampleCommandWithStringArrayProperty(new String[0]);
assertDoesNotThrow(() -> validator.validate(command));
}
{
ExampleCommand command = exampleCommandWithStringArrayProperty(null);
assertDoesNotThrow(() -> validator.validate(command));
}
}
@Test

View File

@@ -298,8 +298,14 @@ public class CollectionPropertyValidatorTests {
}
};
ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("1234", "12345", "123456"));
assertDoesNotThrow(() -> validator.validate(command));
{
ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("1234", "12345", "123456"));
assertDoesNotThrow(() -> validator.validate(command));
}
{
ExampleCommand command = exampleCommandWithStringListProperty(null);
assertDoesNotThrow(() -> validator.validate(command));
}
}
@Test