您无法从Set
使用它们的索引,因为集合没有排序。Set
接口不提供基于索引获取项目的方法,所以这样做.get(index)
to a Set
会给你编译错误。使用List
反而。这样,您就可以使用对象的索引来访问对象。
所以改变Set<Provider> providers
to :
@Valid
List<Provider> providers;
不要忘记@Valid
注释,以便它将向下级联到子对象。
另外,如果th:errors
在表单内部,它应该使用选择表达式指向支持该表单的对象的属性(*{...}
)
<span class="help-block" th:each="provider, status : ${selectedProduct.providers}"
th:if="${#fields.hasErrors('providers[__${status.index}__].url')}"
th:errors="*{providers[__${status.index}__].url}">Error Url
</span>
EDIT
我发现您想要集体访问错误,而不是迭代它们。在这种情况下,您可以创建自定义 JSR 303 验证器。请参阅以下有用的代码片段:
Usage
@ProviderValid
private List<Provider> providers;
ProviderValid注解
//the ProviderValid annotation.
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ProviderValidator.class)
@Documented
public @interface ProviderValid {
String message() default "One of the providers has invalid URL.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
约束验证器
public class ProviderValidator implements ConstraintValidator<ProviderValid, List<Provider>>{
@Override
public void initialize(ProviderValid annotation) { }
@Override
public boolean isValid(List<Provider> value, ConstraintValidatorContext context) {
//...
//validate your list of providers here
//obviously, you should return true if it is valid, otherwise false.
//...
return false;
}
}
完成这些后,您可以轻松获得您在中指定的默认消息@ProviderValid
注释如果ProviderValidator#isValid
只需执行以下操作即可返回 false#fields.hasErrors('providers')