본문 바로가기
에러 기록

Spring validation 과정 중, properties에서 지정한 message 가 출력되지 않음. - 타임리프, 스프링 오류

by 샤샤샤샤 2024. 2. 19.

문제 상황.

오류 메시지를 properties 파일을 이용해 직접 작성하려고 한다. 그러나 옳바르게 문구가 나오지 않고 기본 오류 문구만 출력된다.

test 환경에서 MessageSource 를 주입받아 확인해보면 errors.properties 파일 내부의 문구가 옳바르게 MessageSource 빈에 등록된건 확인이 가능하다.

  1. DTO
@Data
@AllArgsConstructor
public class MemberJoinForm {
    @NotBlank
    private String id;
    @NotBlank
    private String pw;
    @NotBlank
    @Size(min = 2, max = 5)
    private String name;
    @Size(min = 4, max = 15)
    private String nickName;
    @NotBlank
    private String location;
    @Email
    private String mail;
}

 

2.Controller

@Controller
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/member")
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/join")
    public String join(@Validated @ModelAttribute MemberJoinForm memberJoinForm, 
                        BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            log.info("errors={}", bindingResult);
            return "layout/member-join";
        }
        memberService.save(memberJoinForm);
        return "layout/home";
    }
}

 

3.(application.properties), (errors.properties) 파일 내용

# messages 객체 메시지
spring.messages.basename=errors
NotBlank= 필수 입력란을 반드시 입력해 주세요.

 

실행 내용.

 

원인.

 

직관적으로 메시지 표시 과정을 표현하면
errors.properties -> MessageSource -> BindingResult -> 타임리프

순서 인데, 이때 사용자가 지정해준 메시지 내용은 MessageSource 까지만 이동한다. 이후 타임리프에서 BindingResult 에서 발생한 에러 내용 (ex: Size.userCreateRequest.name) 를 확인하여 그에 대응하는 메시지를 MessageSource에서 꺼내오는 원리로 에러 메시지를 출력하게 되는 것이다. 따라서 타임리프에서 오류 처리 코드를 작성해줘야 한다.

요약하자면, 스프링 내부적으로는 에러 메시지가 MessageSource 까지만 처리하고, view단에서 보여주는건 타임리프의 기능이다.

참조 : https://www.inflearn.com/questions/263918/message-%EC%B2%98%EB%A6%AC-%EC%A7%88%EB%AC%B8

 

message 처리 질문 - 인프런

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련

www.inflearn.com

 

해결.

        <div class="mb-3 d-flex justify-content-center">
            <label for="nickname" class="form-label" style="width: 100px"
              >닉네임:</label
            >
            <input
              type="text"
              class="form-control"
              id="nickname"
              name="nickName"
              th:errorclass="field-error"
              style="width: 500px"
              th:field="${JoinForm.nickName}"
            />
            <button type="button" class="btn btn-primary ms-2">
              중복 확인
            </button>
          </div>
          <div class="field-error" th:errors="${JoinForm.nickName}">닉네임 오류</div>

타임리프에서 에러 처리를 해주니 원하는 문구가 출력된다.

만약 타임리프를 사용하지 않고 api로 지정된 오류 문구를 출력하고 싶으면 직접 messageSource에서 꺼내서 사용해야 한다.