BAEL-4223: Displaying Spring error messages with Thymeleaf (#10652)
This commit is contained in:
parent
45b8a5d399
commit
e0b4e6bcd6
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
|
@ -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> {
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue