форма: сообщение об ошибке отображается в каждом поле (список) - PullRequest
0 голосов
/ 27 октября 2018

У меня есть несколько полей ввода, которые являются членами Arraylist одного объекта. И.Е. Приведенный ниже код находится внутри цикла c: forEach.

<tr> <td><form:label path="person[${index}].firstname">First name</form:label></td> <td><form:input path="person[${index}].firstname" /></td> <td><form:errors path="person[${index}].firstname" cssClass="error" /></td> </tr>

Таким образом, ошибки не отображаются вообще. С другой стороны, этот код:

<tr> <td><form:label path="person[${index}].firstname">First name</form:label></td> <td><form:input path="person[${index}].firstname" /></td> <td><form:errors path="person.firstname" cssClass="error" /></td> </tr>

показывает ошибки, но ошибки отображаются в каждом текстовом поле этого поля страницы.

Есть идеи?

1 Ответ

0 голосов
/ 29 октября 2018

В вашем втором подходе,

<tr>
     <td><form:label path="person[${index}].firstname">First name</form:label></td>
     <td><form:input path="person[${index}].firstname" /></td>
     <td><form:errors path="person.firstname" cssClass="error" /></td>
</tr>

Spring свяжет сообщение об ошибке для атрибута с каждым текстовым полем, где вы отобразили <form:errors with path = person.firstname> Это правильное поведение пружины.

Нет прямого способа обработать ошибку ожидаемым образом.

Решение состоит в том, чтобы создать пользовательский Validator for Collection (список объектов) и @ControllerAdvice, который регистрирует этот Validator в WebDataBinders.

Валидатор:

import java.util.Collection;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

/**
 * Spring {@link Validator} that iterates over the elements of a 
 * {@link Collection} and run the validation process for each of them
 * individually.
 *   
 * @author DISID CORPORATION S.L. (www.disid.com)
 */
public class CollectionValidator implements Validator {

  private final Validator validator;

  public CollectionValidator(LocalValidatorFactoryBean validatorFactory) {
    this.validator = validatorFactory;
  }

  @Override
  public boolean supports(Class<?> clazz) {
    return Collection.class.isAssignableFrom(clazz);
  }

  /**
   * Validate each element inside the supplied {@link Collection}.
   * 
   * The supplied errors instance is used to report the validation errors.
   * 
   * @param target the collection that is to be validated
   * @param errors contextual state about the validation process
   */
  @Override
  @SuppressWarnings("rawtypes")
  public void validate(Object target, Errors errors) {
    Collection collection = (Collection) target;
    for (Object object : collection) {
      ValidationUtils.invokeValidator(validator, object, errors);
    }
  }
}

ControllerAdvice:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

/**
 * Controller advice that adds the {@link CollectionValidator} to the 
 * {@link WebDataBinder}.
 * 
 * @author DISID CORPORATION S.L. (www.disid.com)
 */
@ControllerAdvice
public class ValidatorAdvice {

  @Autowired
  protected LocalValidatorFactoryBean validator;


  /**
   * Adds the {@link CollectionValidator} to the supplied 
   * {@link WebDataBinder}
   * 
   * @param binder web data binder.
   */
  @InitBinder
  public void initBinder(WebDataBinder binder) {
    binder.addValidators(new CollectionValidator(validator));
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...