BAEL-4223: Displaying Spring error messages with Thymeleaf (#10652)

This commit is contained in:
freelansam 2021-04-14 01:25:33 +05:30 committed by GitHub
parent 45b8a5d399
commit e0b4e6bcd6
8 changed files with 284 additions and 1 deletions

View File

@ -26,7 +26,15 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@ -0,0 +1,82 @@
package com.baeldung.thymeleaf.errors;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotEmpty(message = "User's name cannot be empty.")
@Size(min = 5, max = 250)
private String fullName;
@NotEmpty(message = "User's email cannot be empty.")
@Size(min = 7, max = 320)
private String email;
@NotNull(message = "User's age cannot be null.")
@Min(value = 18)
private Integer age;
private String country;
private String phoneNumber;
public Long getId() {
return id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setId(Long id) {
this.id = id;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.thymeleaf.errors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class UserController {
@Autowired
private UserRepository repository;
@Autowired
private UserValidationService validationService;
@GetMapping("/add")
public String showAddUserForm(User user) {
return "errors/addUser";
}
@PostMapping("/add")
public String addUser(@Valid User user, BindingResult result, Model model) {
String err = validationService.validateUser(user);
if (!err.isEmpty()) {
ObjectError error = new ObjectError("globalError", err);
result.addError(error);
}
if (result.hasErrors()) {
return "errors/addUser";
}
repository.save(user);
model.addAttribute("users", repository.findAll());
return "errors/home";
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.thymeleaf.errors;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

View File

@ -0,0 +1,22 @@
package com.baeldung.thymeleaf.errors;
import org.springframework.stereotype.Service;
@Service
public class UserValidationService {
public String validateUser(User user) {
String message = "";
if (user.getCountry() != null && user.getPhoneNumber() != null) {
if (user.getCountry()
.equalsIgnoreCase("India")
&& !user.getPhoneNumber()
.startsWith("91")) {
message = "Phone number is invalid for " + user.getCountry();
}
}
return message;
}
}

View File

@ -0,0 +1,6 @@
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.main.allow-bean-definition-overriding=true

View File

@ -0,0 +1,77 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.error {
color: red;
}
</style>
<title>Displaying Error Messages with Thymeleaf</title>
</head>
<body>
<div>
<div>
<h2>Add a Record</h2>
<form action="#" th:action="@{/add}" th:object="${user}"
method="post" class="form">
<div>
<label for="fullName">Name</label> <input type="text"
th:field="*{fullName}" id="fullName" placeholder="Full Name">
<ul>
<li th:each="err : ${#fields.errors('fullName')}" th:text="${err}"
class="error" />
</ul>
</div>
<div>
<label for="email">Email</label> <input type="text"
th:field="*{email}" />
<p th:if="${#fields.hasErrors('email')}"
th:class="${#fields.hasErrors('email')}? error"
th:errors="*{email}" />
</div>
<div>
<label for="age">Age</label> <input type="text" th:field="*{age}"
id="age">
<p th:if="${#fields.hasErrors('age')}"
th:class="${#fields.hasErrors('age')}? error">Invalid Age</p>
</div>
<div>
<label for="country">Country</label> <input type="text"
th:field="*{country}" />
<p th:if="${#fields.hasErrors('country')}" th:errorclass="error"
th:errors="*{country}" />
</div>
<div>
<label for="phoneNumber">Phone Number</label> <input type="text"
th:field="*{phoneNumber}" />
<p th:if="${#fields.hasErrors('phoneNumber')}"
th:errorclass="error" th:errors="*{phoneNumber}" />
</div>
<div th:if="${#fields.hasErrors('global')}">
<h3>Global errors:</h3>
<p th:each="err : ${#fields.errors('global')}" th:text="${err}"
class="error" />
</div>
<h3>All errors in place:</h3>
<div th:if="${#fields.hasAnyErrors()}">
<ul>
<li th:each="err : ${#fields.allErrors()}" th:text="${err}" />
</ul>
</div>
<input type="submit" value="Add Me">
</form>
<h3>This is outside the form:</h3>
<h4>Errors on a single field:</h4>
<div th:if="${#fields.hasErrors('${user.email}')}"
th:errors="*{user.email}"></div>
<h4>All errors:</h4>
<ul>
<li th:each="err : ${#fields.errors('user.*')}" th:text="${err}" />
</ul>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Displaying Error Messages with Thymeleaf</title>
</head>
<body>
<div>
<div>
<h3>Users</h3>
<table class="table">
<tr>
<th>ID</th>
<th>Full name</th>
<th>Email</th>
<th>Age</th>
<th>Country</th>
<th>Phone Number</th>
</tr>
<tr th:each="user: ${users}">
<td th:text="${user.id}" />
<td th:text="${user.fullName}" />
<td th:text="${user.email}" />
<td th:text="${user.age}" />
<td th:text="${user.country}" />
<td th:text="${user.phoneNumber}" />
</tr>
</table>
</div>
</div>
</body>
</html>