[Spring Validation] BindingResult로 에러 처리 깔끔하게 하기

2025. 4. 6. 18:29카테고리 없음

Spring Framework에서는 유효성 검사를 매우 쉽게 처리할 수 있도록 지원한다.

흔히 @Valid@Validated 어노테이션과 함께 BindingResult를 사용한다.

이번 글에서는 BindingResult가 왜 필요한지, 어떻게 동작하는지, 그리고 실제 코드에서 어떻게 사용하는지를 정리해보려 한다.

 

BindingResult란?

BindingResult는 Spring에서 폼 데이터 바인딩 후의 결과를 담고 있는 객체이다.

간단히 말해, 폼 제출 후 서버에서 받은 데이터를 유효성 검사를 통해 검증한 결과를 처리할 수 있도록 도와주는 도구이다.

Spring의 Errors 인터페이스를 상속하며, 유효성 검사 결과(성공/실패)를 함께 담고있으며,

주로 @Valid 어노테이션과 함께 사용된다.

 

BindingResult와 @Valid

@Valid는 객체의 필드를 검증하기 위한 어노테이션이다.

BindingResult는 검증 과정에서 발생한 오류를 담고 있으며, 이를 통해 에러 메시지나, 실패한 필드를 클라이언트에게 제공한다.

 

왜 BindingResult가 필요할까?

@Valid만 단독으로 사용하면, 유효성 검사에 실패할 경우 예외가 터지면서 컨트롤러 자체가 실행되지 않는다.

하지만 BindingResult를 같이 쓰면 에러가 있어도 컨트롤러 메서드는 실행되고,

원하는 방식으로 에러 응답을 커스터마이징할 수 있다.

 

@Valid만으로도 충분하다고 느낄 수 있지만,

다양한 사용자 입력값을 다루고, 에러 메시지를 세밀하게 제어해야 할 때

BindingResult를 활용하면 더 견고한 API를 설계할 수 있다.

 

특히, 유효성 검사 후 흐름 제어가 가능하다는 장점이 있다.

BindingResult를 사용하면, 검증 실패 시 즉시 처리를 중단하고 적절한 오류 메시지를 반환할 수 있다.

hasErrors() 메서드를 통해 에러가 있는지 확인한 후, 적절한 응답을 보내면 된다.

 

BindingResult 장점

위의 사용 필요성을 바탕으로 장점을 정리하면, 유효성 검사 간결화, 코드 일관성 및 간결화 등이 있다.

 

유효성 검사를 쉽게 처리
- Spring은 @Valid와 BindingResult를 사용하면, 객체의 필드를 유효성 검사하고, 그 결과를 자동으로 처리할 수 있다.

 

 

에러 처리의 일관성
- 유효성 검사에서 발생한 오류를 일관되게 처리하고, 클라이언트에게 상세한 오류 메시지를 제공할 수 있다.

 

간결한 코드
- BindingResult를 활용하면 코드가 깔끔해지고, 반복적인 에러 처리 코드를 줄일 수 있다.

 


 

 

예시

간단한 회원가입 폼을 예로 들어 사용자가 입력한 데이터를 서버에서 받아 유효성 검사를 진행하는 과정에서 확인해보고자 한다.

 

- DTO

public class SignupRequestDto {
    @NotBlank(message = "아이디는 필수입니다.")
    private String username;

    @Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.")
    private String password;
}

@NotBlank와 @Size 어노테이션을 통해 username과 password 필드를 유효성 검사를 진행한다.

username은 비어 있으면 안 되고, password는 최소 6자 이상이어야한다.

 

- Controller

@PostMapping("/signup")
public ResponseEntity<?> signup(@Valid @RequestBody SignupRequestDto dto, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return ApiResponse.fail(bindingResult); // 검증 실패 시 응답
    }
    
    return ResponseEntity.ok("회원가입 성공");
}

사용자가 제출한 SignupRequestDto를 @Valid 어노테이션으로 검증하고, BindingResult를 통해 검증 결과를 확인한다.

만약 검증에 실패하면, bindingResult에 에러 정보가 담기고, 이 정보를 기반으로 실패 응답을 클라이언트에 반환한다.

 

- 검증 실패 시 응답

{
  "status": "FAIL",
  "message": "회원가입 실패",
  "errors": [
    { "field": "username", "message": "아이디는 필수입니다." },
    { "field": "password", "message": "비밀번호는 최소 6자 이상이어야 합니다." }
  ]
}