아래와 같이 Bean Validation 사용 시에 message에 {변수명}을 입력할 수 있음. 아래와 같이 작성하면, "값은 1에서 10사이여야 합니다."라는 에러 메시지가 출력됨
@Data
public class MyRequestDTO {
@NotNull
@Range(min = 1, max = 100, message = "값은 {min}에서 {max} 사이여야 합니다.")
private Integer age;
}
BindingResult는 Spring MVC에서 폼 검증 시 오류 정보를 담는 객체이다. Thymeleaf를 사용할 때 이 BindingResult를 활용하여 입력값 유지와 에러 메시지 표시를 쉽게 구현할 수 있다.
1. DTO 정의
@Data
public class UserForm {
@NotBlank(message = "이름은 필수 입력 항목입니다.")
private String name;
@Email(message = "올바른 이메일 형식을 입력하세요.")
@NotBlank(message = "이메일은 필수 입력 항목입니다.")
private String email;
@Size(min = 6, max = 12, message = "비밀번호는 6~12자 사이여야 합니다.")
private String password;
}
2. 컨트롤러 정의
@Controller
public class UserController {
@GetMapping("/register")
public String showForm(Model model) {
model.addAttribute("userForm", new UserForm());
return "register";
}
@PostMapping("/register")
public String register(@Validated @ModelAttribute("userForm") UserForm userForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "register"; // 검증 실패 시 다시 폼 페이지로 이동
}
return "success"; // 성공 시 성공 페이지로 이동
}
}
3. Thymeleaf 폼
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>회원 가입</title>
</head>
<body>
<h2>회원 가입</h2>
<form th:action="@{/register}" th:object="${userForm}" method="post">
<!-- 이름 입력 -->
<label for="name">이름:</label>
<input type="text" id="name" th:field="*{name}" />
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" style="color:red"></span>
<br>
<!-- 이메일 입력 -->
<label for="email">이메일:</label>
<input type="text" id="email" th:field="*{email}" />
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" style="color:red"></span>
<br>
<!-- 비밀번호 입력 -->
<label for="password">비밀번호:</label>
<input type="password" id="password" th:field="*{password}" />
<span th:if="${#fields.hasErrors('password')}" th:errors="*{password}" style="color:red"></span>
<br>
<button type="submit">가입하기</button>
</form>
</body>
</html>
1. BindingResult는 검증 대상 바로 뒤에 위치해야 함
public String register(@Validated @ModelAttribute("userForm") UserForm userForm, BindingResult bindingResult)
2. th:field와 th:errors는 th:object와 함께 사용해야 함
Thymeleaf에서 th:field는 th:object와 연동되므로 폼의 th:object를 선언해야 한다.
- th:field="{name}" → userForm.name 필드와 자동 매핑됨
- th:errors="{name}" → 해당 필드의 오류 메시지를 자동 출력
<form th:action="@{/register}" th:object="${userForm}" method="post">
3. 검증 실패 시 입력값이 유지되어야 함.
th:field를 사용하면 검증 실패 후에도 사용자가 입력한 값이 유지된다.
Spring이 userForm의 값을 다시 모델에 담아 자동으로 기존 입력값을 채운다.
<input type="text" id="name" th:field="*{name}" />
4. @ModelAttribute와 BindingResult 활용