问题描述
我有一个 Product
对象,其中包含一个 Set提供者
.我在 Provider 中用 @NotEmpty
注释了一个变量 url
,现在我想显示一个错误,如果这个字段是空的.我不确定如何正确访问 hasErrors
方法中的字段 providers
.
I've got a Product
object that contains a Set<Provider> providers
. I've annotated within the Provider a variable url
with @NotEmpty
and now I want to display a error, if this field is empty.I'm not sure how I can access the field providers
within the hasErrors
method properly.
表格:
<form action="#" th:action="@{/saveDetails}" th:object="${selectedProduct}" method="post">
<!-- bind each input field to list (working) -->
<input th:each="provider, status : ${selectedProduct.providers}"
th:field="*{providers[__${status.index}__].url}" />
<!-- all the time 'false' -->
<span th:text="'hasErrors-providers=' + ${#fields.hasErrors('providers')}"></span>
<span th:text="'hasErrors-providers[0].url=' + ${#fields.hasErrors('providers[0].url')}"></span>
<!-- not working -->
<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>
<!-- print errors (just for testing purpose) -->
<ul>
<li th:each="e : ${#fields.detailedErrors()}">
<span th:text="${e.fieldName}">The field name</span>|
<span th:text="${e.code}">The error message</span>
</li>
</ul>
</form>
在
中,我收到每个错误 providers[].url
作为 e.fieldName
.我认为它会有一些索引,比如 providers[0].url
等.所以我的问题是,如何正确访问 hasErrors
方法中的字段 providers
以显示错误消息.
Within the <ul>
I receive for each error providers[].url
as e.fieldName
. I thought it would be having some indices like providers[0].url
etc.So my question is, how can I access the field providers
within the hasErrors
method properly to display the error messages.
编辑
控制器:
@RequestMapping(value = "/saveDetails", method = RequestMethod.POST)
public String saveDetails(@Valid @ModelAttribute("selectedProduct") final Product selectedProduct,
final BindingResult bindingResult, SessionStatus status) {
if (bindingResult.hasErrors()) {
return "templates/details";
}
status.setComplete();
return "/templates/overview";
}
推荐答案
您无法使用索引从 Set
中获取项目,因为集合没有顺序.Set
接口不提供基于索引获取项目的方法,因此对 Set
执行 .get(index)
会给你编译错误.使用 List
代替.这样,您就可以使用对象的索引访问对象.
You cannot get an item from a Set
using their index because sets don't have ordering. Set
interface doesn't provide a method of getting an item based on index, so doing .get(index)
to a Set
will give you compile error. Use List
instead. This way, you can access the objects using their index.
所以改变Set提供者
到:
@Valid
List<Provider> providers;
不要忘记 @Valid
注释,以便它会向下级联到子对象.
Don't forget the @Valid
annotation so that it will cascade down to the child objects.
此外,如果 th:errors
在表单内,它应该指向支持该表单的对象的属性,使用选择表达式 (*{...}
)
Also, if th:errors
is inside a form, it should be pointing to a property of the object that backs that form, using Selection Expression (*{...}
)
<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>
编辑
我看到您希望共同访问错误,而不是遍历它们.在这种情况下,您可以创建自定义 JSR 303 验证器.请参阅以下有用的代码片段:
EDIT
I see that you want to access the errors collectively, instead of iterating through them. In that case, you can create your custom JSR 303 validator. See the following useful code fragments :
使用
@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 {};
}
ConstraintValidator
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;
}
}
执行这些操作后,如果 ProviderValidator#isValid
返回 false,只需执行 #fields,您就可以轻松获得在
@ProviderValid
注释中指定的默认消息.hasErrors('providers')
After doing these, you can easily get the default message you specified in the @ProviderValid
annotation if ProviderValidator#isValid
returns false by simply doing #fields.hasErrors('providers')
这篇关于用于显示列表错误的表单绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!