-
[Spring-Error] Global Error 출력이 안되는 문제legacy/Spring 2023. 7. 6. 16:31
문제 발생
회원가입 로직에 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>