자바에서는 null값에 접근할 경우 NPE가 발생하게 되는데
이처럼 올바르지 않은 데이터를 걸러내고 보안을 유지하기 위해 미리 데이터 검증을 하는 과정을 Validation 이라고 한다.
스프링의 Bean validation
을 통해 클래스의 필드에 validation에서 제공하는 특정 어노테이션을 적용하여 제약조건을 정의한다.
spring boot 2.3 version 이상부터는 spring-boot-starter-web 의존성 내부에 있던 validation이 사라졌기 때문에, 의존성을 따로 추가한다.
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.6</version>
</dependency>
유효성 검사에서 사용할 수 있는 어노테이션
@Null // null만 혀용합니다.
@NotNull // null을 허용하지 않습니다. "", " "는 허용합니다.
@NotEmpty // null, ""을 허용하지 않습니다. " "는 허용합니다.
@NotBlank // null, "", " " 모두 허용하지 않습니다.
@Email // 이메일 형식을 검사합니다. 다만 ""의 경우를 통과 시킵니다. @Email 보다 아래 나올 @Patten을 통한 정규식 검사를 더 많이 사용합니다.
@Pattern(regexp = ) // 정규식을 검사할 때 사용됩니다.
@Size(min=, max=) // 문자길이를 제한할 때 사용, int는 불가!
@Max(value = ) // value 이하의 값을 받을 때 사용됩니다.
@Min(value = ) // value 이상의 값을 받을 때 사용됩니다.
@Pattern(regexp = ) // 정규표현식으로 검증식 세울 수 있다.
@Positive // 값을 양수로 제한합니다.
@PositiveOrZero // 값을 양수와 0만 가능하도록 제한합니다.
@Negative // 값을 음수로 제한합니다.
@NegativeOrZero // 값을 음수와 0만 가능하도록 제한합니다.
@Future // 현재보다 미래
@Past // 현재보다 과거
@AssertFalse // false 여부, null은 체크하지 않습니다.
@AssertTrue // true 여부, null은 체크하지 않습니다.
@Valid // 해당 object validation 실행
User
@Data
public class User {
@NotBlank
private String name;
@Max(value = 90)
private int age;
@Email
private String email;
@Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "핸드폰 번호의 양식과 맞지않습니다. 01x-xxx(x)-xxxx")
private String phoneNumber;
}
특정 필드 위에 어노테이션들을 적용 시킨다.
ApiController
@RestController
@RequestMapping("/api")
public class ApiController {
@PostMapping("/user")
public ResponseEntity user(@Valid @RequestBody User user, BindingResult bindingResult) {
System.out.println(user);
if(bindingResult.hasErrors()) {
StringBuilder sb = new StringBuilder();
bindingResult.getAllErrors().forEach(objectError -> {
FieldError field = (FieldError) objectError;
String message = objectError.getDefaultMessage();
System.out.println("field : " + field.getField());
System.out.println(message);
sb.append("문제가 있는 field : " + field.getField() + " , ");
sb.append("에러 message : " + message);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
return ResponseEntity.ok(user);
}
}
@Valid
어노테이션을 유효성 검사를 적용할 클래스 앞에 붙여준다.
BindingResult
클래스를 통해서 유효성 검증에 대한 오류 및 메세지를 담는다.
만약 BindingResult를 사용하지 않는다면 4xx 오류가 발생하면서 요청정보가 호출되지않고 에러페이지로 이동된다.
결과
1. name필드가 공백일 경우
2. 핸드폰 번호가 정규식에 맞지 않는 경우
출처
- 패스트캠퍼스 Java/Spring 예상국 강의
- https://velog.io/@mooh2jj/