[Spring] Validation

이연우·2025년 7월 25일

TIL

목록 보기
49/100

🛡️ 검증(Validation)이란?

  • 클라이언트가 보낸 데이터가 유효한지 검증하는 과정
    → 잘못된 데이터로 인해 시스템에 오류가 발생하는 것을 방지

🍽️ 비유: 식당 주문 시스템

  • 메뉴판에 없는 메뉴를 주문했을 때, 시스템이 막지 않으면 주방이 혼란에 빠짐
    → 검증은 잘못된 요청을 선별사용자에게 안내하는 일종의 Gatekeeper 역할

📌 Validation을 사용하는 이유

이유설명
안정성 확보잘못된 데이터로 인한 시스템 오류 방지
UX 향상유저에게 정확한 피드백 제공
데이터 무결성 유지올바른 데이터만 처리하게 함

💻 Validation의 역할

  1. 검증을 통해 적절한 메세지를 유저에게 보여 주어야 함
  2. 검증 오류로 인해 정상적인 동작을 하지 못하는 경우는 없어야 함
  3. 사용자가 입력한 데이터는 유지된 상태여야 함

🔍 Validation의 종류

구분특징예시
프론트엔드 검증JS, HTML 등에서 즉각 피드백비밀번호 특수문자 경고 등
서버 검증Spring Controller 등에서 체크필수값, 범위 등
DB 검증Not Null, Unique 제약조건 등최종 방어선

→ 💡 모든 계층에서 검증이 필요하며, 특히 서버 검증은 선택이 아닌 필수


📑 BindingResult란?

  • Spring이 제공하는 검증 오류를 담는 객체
    • Errors 인터페이스 확장
    • FieldError, ObjectError 정보 저장
    • 기본 구현체: BeanPropertyBindingResult

⚙️ 동작 방식

상황결과
BindingResult 없음파라미터 바인딩 실패 시 400 오류, Controller 호출 안됨
BindingResult 있음오류가 객체에 담기고, Controller 정상 호출

BindingResult는 반드시 검증 대상 파라미터 바로 뒤에 위치해야 함

💥 파라미터에 BindingResult가 없는 경우

@Data
public class MemberCreateRequestDto {
    private Long point;
    private String name;
    private Integer age;
}
// View 반환
@Controller
public class BingdingResultController {
	
    @PostMapping("/v1/member")
    public String createMemberV1(@ModelAttribute MemberCreateRequestDto request, Model model) {
        // Model에 저장
        System.out.println("/V1/member API가 호출되었습니다.");
        model.addAttribute("point", request.getPoint());
        model.addAttribute("name", request.getName());
        model.addAttribute("age", request.getAge());

        // Thymeleaf Template Engine View Name
        return "complete";
    }

}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Member 생성이 완료되었습니다!</h1>
    <ul>
        <li><span th:text="${point}">포인트</span></li>
        <li><span th:text="${name}">이름</span></li>
        <li><span th:text="${age}">나이</span></li>
    </ul>
</body>
</html>

→ 컨트롤러 호출조차 안 됨
→ 사용자는 갑작스러운 Error 페이지를 보게 됨

✅ 파라미터에 BindingResult가 있는 경우

@Controller
public class BindingResultController {

    @PostMapping("/v2/member")
    public String createMemberV2(
            // 1. @ModelAttribute 뒤에 2. BindingResult가 위치한다.
            @ModelAttribute MemberCreateRequestDto request,
            BindingResult bindingResult,
            Model model
    ) {

        System.out.println("/V2/member API가 호출되었습니다.");

        // BindingResult의 에러 출력
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        System.out.println("allErrors = " + allErrors);

        // Model에 저장
        model.addAttribute("point", request.getPoint());
        model.addAttribute("name", request.getName());
        model.addAttribute("age", request.getAge());

        return "complete";
    }
    
}

→ 잘못된 값만 오류로 처리하고 나머지 필드는 정상적으로 바인딩
→ 에러 메시지와 함께 유저에게 피드백 제공 가능


📌 정리 요약

항목설명
BindingResult검증 실패 시 오류 정보 저장 객체
위치@ModelAttribute 또는 @Valid 바로 뒤
사용 이유컨트롤러 진입 차단 없이 에러 처리 가능
예외 상황필드명 오류, 타입 불일치, 누락된 필드 등

📋 실전 Validation 전략

계층역할예시
프론트UX 개선, 빠른 피드백JS 알림창 등
서버 (Spring)핵심 검증 로직@Valid + BindingResult
DB최종 방어선Not Null, Unique 등 제약조건

0개의 댓글