Проверка данных формы Thymeleaf Spring Boot с помощью Bean Validator

Введение Проверка данных формы - очень распространенный и элементарный шаг в создании любого веб-приложения с пользовательским вводом. Мы хотим убедиться, что соблюдаются определенные диапазоны и соблюдаются определенные форматы. Например, мы хотим убедиться, что пользователю не -345 лет или что его адрес электронной почты действителен. Есть много способов проверить данные формы - и метод, который вы используете, зависит от вашего приложения. В общем, вам нужно выполнить проверку на стороне клиента [client-side-fo

Вступление

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

Есть много способов проверить данные формы - и метод, который вы используете, зависит от вашего приложения. В общем, вы захотите выполнить проверку на стороне клиента , а также проверку на стороне сервера . Проверка на стороне клиента гарантирует, что неотфильтрованные данные даже не доходят до серверной части, в то время как проверка на стороне сервера гарантирует, что неправильные данные не будут обрабатываться дальше.

В этой статье мы расскажем, как выполнять проверку данных формы в Spring Boot с Thymeleaf в качестве механизма шаблонов.

Мы будем использовать встроенный Bean Validation API Spring Boot, который делает этот процесс простым и понятным.

Зависимость Maven проверки загрузки Spring

Spring Boot позволяет нам определять критерии проверки с помощью аннотаций. В вашей модели предметной области вы можете просто аннотировать поля с ограничениями, и она обеспечит их соблюдение.

Чтобы аннотации валидации работали, нам нужно добавить следующую зависимость:

 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-validation</artifactId> 
 </dependency> 

Модель домена

Давайте определим простой POJO с несколькими полями, которые мы хотим проверить:

 @Entity 
 public class Person { 
 
 @Id 
 @GeneratedValue(strategy= GenerationType.AUTO) 
 private Long id; 
 
 @NotEmpty 
 @Size(min = 5) 
 private String fullName; 
 
 @NotEmpty 
 @Email 
 private String email; 
 
 @NotNull 
 @Min(value = 18) 
 private Integer age; 
 
 // Getters and Setters 
 
 } 

Теперь давайте разберемся с аннотациями, которые мы использовали:

  • @NotEmpty - используется для ограничения поля типа String , Collection , Map или Array чтобы оно не было null или пустым.
  • @Size([min = x, max = y]) - используется для определения правил для размера String , Collection , Map или Array .
  • @Email - помогает нам проверить строку на соответствие регулярному выражению, которое определяет структуру действительного электронного письма.
  • @NotNull - сообщает Spring, что поле не должно быть нулевым, но может быть пустым .
  • @Min и @Max используются для указания пределов переменной. Например, @Min может быть установлен, скажем, 18.

Уровень сохраняемости - репозиторий

Чтобы создать простой репозиторий CRUD, все, что нам нужно сделать, это расширить JpaRepository и предоставить нашу модель предметной области и тип данных идентификатора:

 @Repository 
 public interface PersonRepository extends JpaRepository<Person, Long> { 
 } 

Создание формы с тимелеафа

Теперь давайте создадим простую форму, используя HTML и Bootstrap для сбора информации:

 <form th:action="@{/add}" th:object="${person}" method="post" class="form"> 
 <div class="form-group"> 
 <label for="fullName">Name</label> 
 <input class="form-control" type="text" th:field="*{fullName}" id="fullName" placeholder="Full Name"> 
 <div class="alert alert-warning" th:if="${#fields.hasErrors('fullName')}" th:errors="*{fullName}"></div> 
 </div> 
 <div class="form-group"> 
 <label for="email">Email</label> 
 <input class="form-control" type="text" th:field="*{email}" id="email" placeholder="Email"> 
 <div class="alert alert-warning" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div> 
 </div> 
 <div class="form-group"> 
 <label for="age">Age</label> 
 <input class="form-control" type="text" th:field="*{age}" id="age" placeholder="Age"> 
 <div class="alert alert-warning" th:if="${#fields.hasErrors('age')}" th:errors="*{age}"></div> 
 </div> 
 <input type="submit" class="btn btn-success" value="Add User"> 
 </form> 

Форма указывает на /add и отправляет запрос POST Поля в нашем объекте fullName , age и email находятся в форме, обозначенной th:field . Поскольку у нас есть th:object=${person} , мы можем ссылаться на этот person , заменив его на * перед полями.

*{fullName} совпадает с ${person.fullName} . Каждый вход также имеет скрытый <div> который отображается только в том случае, если вызовы ${#fields.hasErrors()} true . Если ошибок нет, этот div не существует. Если есть, th:errors позволяет нам указать сообщение. Если мы просто передадим поле, вызывающее ошибку, такое как th:errors="*{age}" , для этого поля будет использоваться сообщение по умолчанию от Bean Validator API.

В результате получается такая форма:

базовая формаhtml{.ezlazyload}

Поскольку эти сообщения не очень удобны для пользователя, мы захотим настроить их, предоставив свои собственные сообщения.

Контроллер

Теперь давайте создадим контроллер, который будет обрабатывать запрос на сохранение Person в базе данных. Как обычно, у нас будет @GetMapping() для отображения формы и @PostMapping для обработки запроса. В сигнатуре метода @PostMapping мы аннотируем POJO с помощью @Valid .

Аннотация @Valid запускает Bean Validator, чтобы проверить, соответствуют ли поля, заполненные в объекте, аннотациям, которые мы использовали в определении класса. Если вы не используете @Valid , она ничего не проверяет, и даже значения, которых вы не могли ожидать, могут быть заполнены в объекте.

В нашем случае Person person - это объект, заполненный входными данными формы:

 @GetMapping("/add") 
 public String showAddPersonForm(Person person) { 
 return "add-person"; 
 } 
 
 @PostMapping("/add") 
 public String addPerson(@Valid Person person, BindingResult result, Model model) { 
 if (result.hasErrors()) { 
 return "add-person"; 
 } 
 repository.save(person); 
 return "redirect:/index"; 
 } 

Если есть какие-либо проблемы с этим Person , в ${fields} будут ошибки, связанные с полем, вызвавшим ошибку.

Настройка сообщений об ошибках

Чтобы установить собственное сообщение для любого ограничения проверки, вы можете использовать опцию message

 @NotEmpty(message = "Field can't be empty!) 
 private String field; 

Вы можете просто записать эти сообщения в своей модели, вот так. Тем не менее, считается хорошей практикой помещать сообщения проверки в properties , на который вы можете ссылаться. Это сделано, поскольку вы можете объединить все сообщения проверки вместе и обновить их, если модели будут изменены позже.

Сделаем наш ValidationMessages.properties в src/main/resources :

 Size.Person.FullName=The Full Name should have at least 5 characters 

Затем мы @Size Person и предоставим это свойство как message аннотации @Size:

 @NotEmpty(message = "The Full Name can't be null") 
 @Size(min = 5, message = "{Size.Person.FullName}") 
 private String fullName; 

Вернемся к нашей форме и посмотрим, как она теперь выглядит:

настраиваемые сообщения об ошибках Spring boot beanvalidator{.ezlazyload}

Заключение

В этой статье мы рассмотрели, как использовать API-интерфейс Bean Validator, который Spring Boot использует для легкого выполнения проверки данных формы с помощью Thymeleaf.

Мы создали модель предметной области, аннотировали наши поля с помощью ограничений Bean Validator. Затем мы создали репозиторий и контроллер для отображения формы и ее обработки, а также для сохранения соответствующей информации в Person , убедившись, что поля проверены с @Valid аннотации @Valid.

Вы можете найти исходный код на GitHub .

comments powered by Disqus