ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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>
Designed by Tistory.