검증(Validation)
특정 데이터(주로 클라이언트의 요청 데이터)의 값이 유효한지 확인하는 단계를 의미한다.
Controller의 주요한 역할 중 하나는 Validation 이다. HTTP 요청이 정상인지 검증한다.
Validation이란?
식당 메뉴판(specification)에 있는 메뉴만 주문이 가능하다.
안내를 통해 제대로된 주문을 받을 수 있다.
Validation을 사용하는 이유
주문서 작성 페이지에서 잘못된 입력값으로 인해 서버에 오류가 발생한다면?
ex) 휴대폰 번호에 숫자가 아닌 문자가 들어간 경우
서버의 문제로 인해 작성 페이지에서 Error 페이지로 이동된다면?
Error 페이지로 이동되어 작성중인 폼이 모두 리셋되어 다시 작성해야 한다면?
이러한 서비스의 유저는 굉장한 불편함을 겪게된다.
Validation의 역할
실제 서버를 운영하다보면 기능의 의도와 다른 다양한 사용 방법들을 보게된다. ex) Enter로 입력이 완료되도록 만들었지만 누군가는 Click, Tab + Enter를 누르듯
검증의 종류
기본적으로 프론트, 서버, 데이터베이스 모두 검증을 꼼꼼하게 하는것이 바람직하다. Validation으로 수많은 Error와 문제들을 방지할 수 있다.
BindingResult
Spring에서 기본적으로 제공되는 Validation 오류를 보관하는 객체이다. 주로 사용자 입력 폼을 검증할 때 많이 쓰이고 Field Error와 ObjectError를 보관한다.

Errors 인터페이스를 상속받은 인터페이스이다.
Errors 인터페이스는 에러의 저장과 조회 기능을 제공한다.
BindingResult는 addError() 와 같은 추가적인 기능을 제공한다.
BeanPropertyBindingResult 이다.파라미터에 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>Postman
- 정상 요청

complete페이지로 이동한다.

파라미터에 BindingResult가 있는 경우
주의사항 : 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";
}
}Postman
정상 요청


@ModelAttribute 필드 or 객체에 파라미터 바인딩 오류가 발생
@ModelAttribute는 파라미터를 필드 하나하나에 바인딩한다. 파라미터에 Binding Result가 함께 있는 경우 만약 그중 하나의 필드에 오류가 발생하면 해당 필드를 제외하고 나머지 필드들만 바인딩 된 후 Controller가 호출된다.