👩🏻‍💻 Programming/SpringBoot

Spring Boot와 Validation (1)

한국의 메타몽 2021. 8. 11. 01:10

 

Validation이란?

 

데이터가 부정확(불완전)한지 확인하기 위해서 사용되는 처리이다.

예를들어 Java에서 null값에 대해서 접근하려고 할 때 null pointer exception이 발생 함으로, 이러한 부분을 방지하기 위해 미리 검증하는 과정을 Validation이라고 한다.

 

단순하게 아래와 같은 코드들도 Validation이라고 할 수 있다.

public void run(String account, String pw){
	if(account==null||pw==null) return; 
}

하지만 이렇게 if-else문으로 검증을 하다가는 반복되는 부분이 많아지며, 따로 메소드를 빼더라도 반복문이 많아지는 것은 변함이 없다.

SpringBoot에서는 Annotation을 기반으로 Validation을 제공해주며, 예를들어 @Notnull, @Notempty등이 있다.

SpringBoot에서 제공해주는 Validation Annotation을 통해 반복적인 코드 없이 간결하게 코드 유효성을 체크할 수 있다.

 

 

Validation의 간단한 예시

 

[User.java]

public class User {
    private String name;
    private int age;
    @Email
    private String email;
    private String phoneNumber;
    // 이하 getter, setter, tostring 존재

user객체의 이메일에 @Email Validation을 적용했다.

 

[ApiController.java]

    @PostMapping("/user")
    public User user(@Valid @RequestBody User user){ // @Valid를 적어야 해당 객체 내부의 validation annotation을 검사
        System.out.println(user);
        return user;
    }

User를 Echo하는 코드이다. 이때 주의점은 매개변수 내부에 @Valid를 적어줘야 해당 객체의 Validation Annotation이 검사된다는 점이다.

 

[결과]

 

Postman로 Post한 Json 데이터

2021-08-11 00:56:47.316  WARN 1174 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.example.validation.dto.User com.example.validation.controller.ApiController.user(com.example.validation.dto.User): [Field error in object 'user' on field 'email': rejected value [dm-naver.com]; codes [Email.user.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@716c8fc6,.*]; default message [must be a well-formed email address]] ]

결과적으로 400 Error와 함께 경고 코드가 출력된다. 위의 코드에서 보면 마지막 부분에 'must be a well-formed email address'가 적혀있는데, 말 그대로 옳바른 이메일 형식이 아니라서 에러가 발생한 것이다.

 

email을 dm@naver.com과 같이 정상적인 이메일 타입으로 적어주면 정상작동된다.

 

 

Validation 개선

 

하지만 위 코드에서 결과로 출력되는 경고 코드는 굉장히 길고 한눈에 들어오지 않는다.

이를 개선해서 사용자가 정확히 어디에서 무슨 실수를 만들었는지를 알려주는, 보다 가독성 좋은 코드를 만들어보자.

 

[ApiController.java]

public class ApiController {
    @PostMapping("/user")
    public ResponseEntity user(@Valid @RequestBody User user, BindingResult bindingResult){ // @Valid를 적어야 해당 객체 내부의 validation annotation을 검사
        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);
    }
}

 

[User.java]

public class User {
    private String name;
    private int age;
    @Email(message = "이메일 양식을 다시 입력해주세요. (아이디@도메인.com)")
    private String email;
    private String phoneNumber;
    // 이하는 getter, setter, toString 존재

@Email에 message를 추가하여 validation error가 발생할 경우 출력되는 메세지를 작성하였다.

 

 

[결과]

Postman의 입력과 출력 결과

 

SpringBoot의 Console창 결과