Spring boot user registration - получение ошибок валидации в пользовательский интерфейс - PullRequest
0 голосов
/ 22 декабря 2018

Я изучаю Springboot и пытаюсь проследить, как ошибки регистрации попадают в пользовательский интерфейс в этом примере Baeldung Процесс регистрации добраться до пользовательского интерфейса.Однако реализация на веб-сайте Baeldung отличается от проекта Baeldung Github.

В примере на веб-странице у них есть контроллер регистрации, который выглядит следующим образом:

@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
public ModelAndView registerUserAccount
  (@ModelAttribute("user") @Valid UserDto accountDto, 
  BindingResult result, WebRequest request, Errors errors) {    
     User registered = new User();
     if (!result.hasErrors()) {
        registered = createUserAccount(accountDto, result);
      }
     if (registered == null) {
        result.rejectValue("email", "message.regError");
     }
   // rest of the implementation
}

private User createUserAccount(UserDto accountDto, BindingResult result) {
  User registered = null;
  try {
      registered = service.registerNewUserAccount(accountDto);
  } catch (EmailExistsException e) {
      return null;
  }    
  return registered;
}

С соответствующим HTML-кодом:

<div>
    <label th:text="#{label.user.email}">email</label>
    <input type="email" th:field="*{email}"/>
    <p th:each="error : ${#fields.errors('email')}" h:text="${error}">Validation error</p>
</div>

Я понимаю, что метод createUserAccount может выдавать и выдавать ошибку с исключением, которое в конечном итоге добавляется к результирующему объекту, который проходит через HTML через thymeleaf.

Однако в связанном github проект на той же веб-странице, реализация очень отличается, и я не слежу за тем, как ошибки приводят к UI.

Контроллер теперь выглядит так:

    @RequestMapping(value = "/user/registration", method = RequestMethod.POST)
    @ResponseBody
    public GenericResponse registerUserAccount(@Valid final UserDto accountDto, final HttpServletRequest request) {
    LOGGER.debug("Registering user account with information: {}", accountDto);
    final User registered = userService.registerNewUserAccount(accountDto);
    eventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), getAppUrl(request)));
    return new GenericResponse("success");
    }

Это вызывает registerNewUserAccount метод, который выглядит следующим образом:

    @Override
    public User registerNewUserAccount(final UserDto accountDto) {
    if (emailExist(accountDto.getEmail())) {
        throw new UserAlreadyExistException("There is an account with that email adress: " + accountDto.getEmail());
    }
    // rest of method

Класс UserAlreadyExistException выглядит следующим образом:

public final class UserAlreadyExistException extends RuntimeException {

    public UserAlreadyExistException() {
        super();
    }

    public UserAlreadyExistException(final String message, final Throwable cause) {
        super(message, cause);
    }

    public UserAlreadyExistException(final String message) {
        super(message);
    }

    public UserAlreadyExistException(final Throwable cause) {
        super(cause);
    }
}

Даже регистрационный HTML теперь отличается и, похоже, не использует Thymeleaf для ошибок:

<div class="form-group row">
    <label class="col-sm-3" th:text="#{label.user.email}">email</label>
    <span class="col-sm-5"><input type="email" class="form-control" name="email" value="" required="required"/></span>                    
    <span id="emailError" class="alert alert-danger col-sm-4" style="display:none"></span>
</div>

Это все бВозникает вопрос: как это исключение и связанные сообщения всплывают обратно в пользовательский интерфейс?В реализации на исходном примере были различные ошибки (например, @NotEmtpty), которые будут представлены в пользовательском интерфейсе.

1 Ответ

0 голосов
/ 22 декабря 2018

Я думаю, что вы сбиваете с толку: как сообщение об ошибке передается на первую страницу, так как в контроллере нет кодов для него.Правильно ли мое понимание?

Краткий ответ:

Это делается в глобальном обработчике исключений, расположенном по адресу: https://github.com/Baeldung/spring-security-registration/blob/master/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java

Подробнее:

Обычно дляВ контроллерах Spring мы будем использовать глобальный обработчик исключений для перехвата всех исключений, которые выбрасываются из методов контроллера, хотя само исключение может быть из кода служб.Метод-обработчик аннотируется с помощью @ExceptionHandler.

Таким образом, поток сообщения об ошибке для случая «пользователь уже существует» выглядит следующим образом:

  1. javascript интерфейса пользователя выполняет всю локальную проверкунапример, формат электронной почты, длина пароля и т. д. Только когда все эти проверки пройдены, он вызывает API для регистрации нового пользователя.
  2. контроллер получает запрос на регистрацию пользователя.
  3. контроллер вызывает сервисный метод длязарегистрировать нового пользователя.
  4. методы обслуживания выдают уже существующее исключение при обнаружении.
  5. контроллер не перехватил исключение, поэтому он выбрасывает метод контроллера.
  6. globalОбработчик исключений контроллера перехватил это исключение и сгенерировал ответ об ошибке dto, заполнив сообщения об ошибках, которые предоставляются message.properties для соответствующей локали к ответу об ошибке.Свойства расположены в src / main / resources, а имя файла объявляет локаль.После заполнения ответа об ошибке он возвращает его, так что пружина ответит этому объекту на передний конец.
  7. передний конец получит ответ.Javascript проверить, если это ошибка.И если да, то он проверяет, к какому типу ошибок он относится, соответственно.

Поначалу такой поток может быть не очень интуитивно понятным.Но как только вы поймете это, вы будете счастливы, используя это.Это может сохранить много кодов для обработки ошибок в контроллере.

Я думаю, что controllerAdvice реализован с использованием AOP, который является очень мощным инструментом.Если вы хотите узнать больше, вы можете продолжить исследование самостоятельно.

Относительно обработки ошибок валидации:

Обработчик исключений наследует ResponseEntityExceptionHandler , который обрабатывает результат валидации из валидацииполезной нагрузки запроса.Смотрите первые два метода переопределения обработчика.Для меня это тоже новость, приятно знать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...