用于显示列表错误的表单绑定

时间:2015-12-10 11:23:16

标签: spring-mvc thymeleaf

我有一个包含Product的{​​{1}}对象。我在提供者中注释了Set<Provider> providers变量url,现在我想显示错误,如果此字段为空。 我不确定如何正确访问@NotEmpty方法中的字段providers

形式:

hasErrors

<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> 我收到的每个错误<ul>providers[].url。我认为它会有一些像e.fieldName等索引。 我的问题是,如何正确访问providers[0].url方法中的字段providers以显示错误消息。

修改

控制器:

hasErrors

1 个答案:

答案 0 :(得分:4)

您无法使用他们的索引从Set获取某个项目,因为小组没有订购。 Set界面没有提供基于索引获取项目的方法,因此对.get(index)执行Set会给出编译错误。请改用List。这样,您就可以使用索引访问对象。

所以将Set<Provider> providers更改为:

@Valid
List<Provider> providers;

不要忘记@Valid注释,以便它会级联到子对象。

此外,如果th:errors位于表单内,则应使用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验证器。请参阅以下有用的代码片段:

<强>用法

@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;
    }
}

执行这些操作后,只需执行@ProviderValid

,即可ProviderValidator#isValid返回false,您可以轻松获取在#fields.hasErrors('providers')注释中指定的默认消息