티스토리 뷰
문제 발생
회원가입 로직에 BindingResult를 사용하여 오류를 처리하고 있었다. Global Error가 정상적으로 작동하는지 테스트를 하려고 다음과 같이 로직을 작성했다.
Controller
@PostMapping("/register")
public String checkRegister(User user, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
if(user.getUserName() == "" || user.getUserName() == null) {
bindingResult.rejectValue("loginId", "required");
}
if(user.getLoginPassword() == "" || user.getLoginPassword() == null) {
bindingResult.rejectValue("loginPassword", "required");
}
if(user.getUserName() == "" || user.getUserName() == null) {
bindingResult.rejectValue("userName", "required");
}
if(user.getUserAge() == null) {
bindingResult.rejectValue("userAge", "required");
}
if(bindingResult.hasErrors()) {
bindingResult.addError(new ObjectError("user", "회원가입 실패"));
return "/register";
}
User savedUser = new User();
savedUser.setLoginId(user.getLoginId());
savedUser.setLoginPassword(user.getLoginPassword());
savedUser.setUserName(user.getUserName());
savedUser.setUserAge(user.getUserAge());
userRepository.save(user);
redirectAttributes.addAttribute("status", "success");
return "redirect:/home";
}
View
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:if="${#fields.hasGlobalErrors()}">
<p th:each="error : ${#fields.globalErrors()}" th:text="${error}"></p>
</div>
<form th:action th:object="${user}" method="post">
<fieldset>
<legend>회원가입</legend>
<label for="loginId">아이디</label>
<input type="text" th:field="*{loginId}" th:placeholder="#{inputId}">
<br>
<label for="loginPassword">비밀번호</label>
<input type="password" th:field="*{loginPassword}" th:placeholder="#{inputPassword}">
<br>
<label for="userName">이름</label>
<input type="text" th:field="*{userName}" th:placeholder="#{inputName}">
<br>
<label for="userAge">나이</label>
<input type="text" th:field="*{userAge}" th:placeholder="#{inputAge}">
</fieldset>
<button>제출</button>
</form>
</body>
</html>
전체 코드를 알 필요는 없고 Controller에서는 글로벌 오류를 저장하는 부분, View에서는 글로벌 오류를 출력하는 부분을 보면 된다. 이 글을 읽는 사람들은 글로벌 오류가 무엇인지 당연히 알겠지만 혹시나 하는 마음에 코드를 남긴다.
if(bindingResult.hasErrors()) {
bindingResult.addError(new ObjectError("user", "회원가입 실패"));
return "/register";
}
<body>
<div th:if="${#fields.hasGlobalErrors()}">
<p th:each="error : ${#fields.globalErrors()}" th:text="${error}"></p>
</div>
<form th:action th:object="${user}" method="post">
생략...
</form>
</body>
오류 출력
확대해서 보길 바란다.
해결
인텔리J가 왜 오류가 발생하는지 알려준다.
예외 처리 템플릿에서 'global' 식을 사용하여 오류를 바인딩할 수 없다. form 안에서 'global' 식을 사용하고 있는지 확인해라.
내가 form 밖에다가 Global Error를 사용해도 된다고 생각했던 이유는 th:if를 사용하기 때문에 오류가 저장되어 있으면 오류를 출력할 것이고 아니면 출력 안 할 것으로 생각했다.
최종적으로 다음과 같이 수정하면 오류가 해결된다.
오류 코드
<body>
<div th:if="${#fields.hasGlobalErrors()}">
<p th:each="error : ${#fields.globalErrors()}" th:text="${error}"></p>
</div>
<form th:action th:object="${user}" method="post">
생략...
</form>
</body>
수정 코드
<body>
<form th:action th:object="${user}" method="post">
<div th:if="${#fields.hasGlobalErrors()}">
<p th:each="error : ${#fields.globalErrors()}" th:text="${error}"></p>
</div>
</form>
</body>