[Spring Boot] Validation, Custom Validation

이맑음·2021년 9월 23일
0

Spring Boot

목록 보기
9/21
post-thumbnail

Validation

  • null pointer exception 같은 부분을 방지하기 위해서 미리 검증 하는 과정이다.
  • 검증할 값이 많은 경우 코드가 길어진다.
  • 구현에 따라 service logic과 분리가 필요하다.
  • 검증 코드들이 흩어져 있는 경우 확인이 어려우며, 재사용의 한계가 있다.
  • 따라서 validation 부분은 변화가 있으면 안되며, business logic이 들어가면 안된다.
  • 어노테이션 : Size, NotNull, Past, Pattern(정규식 적용), Max, AssertTrue, Valid 등이 있다.
  • build.gradle에 추가
implementation 'org.springframework.boot:spring-boot-starter-validation'

Custom Validation

  • AssertTrue/Fals와 같은 method 지정을 통해서 custom logic 적용이 가능하다. (재사용불가능)
  • ConstraintValidator를 적용하여 재사용이 가능한 custom logic 적용이 가능하다.

예제1-AssertTrue

  • dto/Car
public class Car {

    @NotBlank
    private String name;

    @NotBlank
    @JsonProperty("car_number")
    private String carNumber;

    @NotBlank
    @JsonProperty("TYPE")
    private String type;
}
  • dto/User
public class User {

    @NotBlank
    private String name;

    @Max(value = 90) //age는 90세 이하까지
    private int age;

    @Email //spring에서 제공
    private String email;

    @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "핸드폰 번호의 양식과 맞지 않습니다. 01x-xxx(x)-xxxx")
    private String phoneNumber;

    @Valid
    private List<Car> cars;'
    //Car class에 작성한 validation이 실행되려면 객체에 @Valid를 사용해야 한다.

    @AssertTrue(message = "yyyyMM 의 형식에 맞지 않습니다.")
    public boolean isreqYearMonthValidation() { //boolean은 is 키워드를 붙여야 한다.
        try {
            LocalDate localDate = LocalDate.parse(getReqYearMonth()+"01", DateTimeFormatter.ofPattern("yyyyMMdd"));
            //yyyyMM까지 입력 받기 때문에 뒤에 day를 붙여 검증을 진행한다.
        }
        catch (Exception e) {
            return false;
        }

        return true;
    }
  • controller/ApiController
@RestController
@RequestMapping("/api")
public class ApiController {

    @PostMapping("/user")
    public ResponseEntity user(@Valid @RequestBody User user, BindingResult bindingResult) { 
    //@Valid에 대한 결과가 bindingResult에 담김
    //객체에서 작성한 validation이 실행되려면 메서드에 @Valid를 사용해야 한다.

        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());
        }

        System.out.println(user);

        return ResponseEntity.ok(user);
    }
}

예제2-custom validation

0개의 댓글