spring-mvc - 用于显示列表错误的表单绑定(bind)

标签 spring-mvc thymeleaf

我有一个 Product包含 Set<Provider> providers 的对象.我在 Provider 中注释了一个变量 url@NotEmpty现在我想显示一个错误,如果这个字段是空的。 我不确定如何访问字段 providershasErrors 内方法正确。

表格:

<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 这样的索引等等 所以我的问题是,如何访问字段 providershasErrors 内正确显示错误消息的方法。

编辑

Controller :

@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接口(interface)不提供基于索引获取项目的方法,所以做 .get(index)Set会给你编译错误。使用 List反而。这样,您就可以使用它们的索引访问对象。

所以改变Set<Provider> providers到:

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

编辑

我看到您想集中访问错误,而不是遍历它们。在这种情况下,您可以创建自定义 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 {};
}

约束验证器

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只需执行 #fields.hasErrors('providers') 即可返回 false

关于spring-mvc - 用于显示列表错误的表单绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34200637/

相关文章:

java - 如何为模型中的每个元素生成编辑模式?

spring - RedirectAttributes 在 Spring 3.1 中给出 IllegalStateException

java - 如何进行基于注解的RequestMapping

java - Spring mvc加载资源的问题

Spring 和 thymeleaf : changing locale and stay on the current page

java - Spring MVC、Thymeleaf URL

authentication - 登录尝试失败后将用户名保留在表单输入字段中(Java/Spring-security)

Java Spring rest 返回未经授权的 json

java - 在 Spring MVC 应用程序中打开静态文件

java - Spring thymeleaf 实现