스프링부트 Validation
: NullPointerExeption 발생을 방지하기 위해 미리 검증을 하는 과정
- 검증해야 할 값이 많은 경우 코드의 길이가 길어진다.
- Service Logic과 분리가 필요하다.
- 재사용의 한계가 생긴다.
종류
- @Size : 문자 길이 측정
- @NotNull : null불가
- @NotEmpty : null, ""불가
- @NotBlank : null, "", " "불가
- @Past : 과거 날짜
- @PastOrPreset : 오늘이거나 과거날짜
- @Future : 미래 날짜
- @FutureOrPresent : 오늘이거나 미래 날짜
- @Pattern : 정규식 적용
- @Max : 최대값
- @Min : 최소값
- @AssertTrue/False : 별도 Logic 적용
- @Valid : 해당 Object Validation실행
적용
1) gradle
: gradle link2) validation spec
: The Bean references3) 적용 : 핸드폰 정규식 적용 테스트
: "^\d{2,3}-\d{3,4}-\d{4}$"
public class ValidationUser {
@NotBlank
private String name;
@Min(value = 0)
@Max(value = 90)
private int age;
@Email
private String email;
@Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "핸드폰의 양식과 맞지 않습니다. xxx-xxxx-xxxx")
@JsonProperty("phone_number")
private String phoneNumber;
}
@RestController
@RequestMapping("/valid-api")
public class ValidationTestController {
@PostMapping("/user")
public ResponseEntity user(@Valid @RequestBody ValidationUser user, BindingResult bindingResult) {
System.out.println(user);
if(bindingResult.hasErrors()) {
StringBuilder sb = new StringBuilder();
bindingResult.getAllErrors().forEach(objectError -> {
FieldError field = (FieldError) objectError;
String msg = objectError.getDefaultMessage();
System.out.println("field : " + field.getField() + " // message : " + msg);
sb.append("field : " + field.getField());
sb.append("\t");
sb.append("message : " + msg);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
return ResponseEntity.ok(user);
}
}
사용자 정의 Validation
: 규격이 맞지 않는 것을 적용해야 하는 경우에는 사용자 정의하여 사용할 필요가 있음.
- AssertTrue/False
- ConstraintValiator
@Constraint(validatedBy = {YearMonthValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface YearMonth {
String message() default "yyyyMM 형식에 부합되지 않습니다.";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
String pattern() default "yyyyMM";
}
public class YearMonthValidator implements ConstraintValidator<YearMonth, String> {
private String pattern;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// yyyyMM
try {
LocalDate localDate = LocalDate.parse(value + "01", DateTimeFormatter.ofPattern(this.pattern + "dd"));
} catch (Exception e) {
return false;
}
return true;
}
@Override
public void initialize(YearMonth constraintAnnotation) {
this.pattern = constraintAnnotation.pattern();
}
}