minlog
article thumbnail

 

Validation

벨리데이션 (Validation) 이란 null pointer exception이 발생하는 부분을 방지 하기 위해서 미리 검증하는 과정. 

  • 검증해야할 값이 많을 경우 코드가 길어진다.
  • 구현에 따라 다를 수 있지만 서비스 로직과의 분리가 필요하다.
  • 흩어져 있는 경우 어디서 검증을 하는지 알기 어렵고 재사용의 한계가 있다.

스프링에서는 어노테이션 기반으로 제공하고 있다. ( 변수에 붙혀서 사용하면됨 )

 

Annotation Validation 의미
@Size 문자 길이 측정 (int 타입은 불가능)
@NotNull null 불가능
@NotEmpty null," " 불가능
@NotBlank null, " ", 스페이스도 불가능
@Email 이메일 형식
@Past 과거 날짜
@PastOrPresent 오늘이거나 과거 날짜
@Future 미래 날짜
@FutureOrPesent 오늘이거나 미래 날짜
@Pattern 정규식 적용
(ex: 이메일, 핸드폰번호, 주민등록번호 등...)
@Pattern(regexp="정규식" , message="오류 내용 입력")
@Max 최대값
(ex: @Max(90)
@Min 최소값
@AssertTrue/False 별도 로직 적용
@Valid 해당 object validation  실행

 

 

🍫 bean validation 스펙 정의 살펴보기

어떤 어노테이션이 제공되고 사용되는지 확인할 수 있다.

Jakarta Bean Validation - Bean Validation 2.0 (JSR 380)

 

Jakarta Bean Validation - Bean Validation 2.0 (JSR 380)

Bean Validation 2.0 focused on the following topics: support for validating container elements by annotating type arguments of parameterized types e.g. List<@Positive Integer> positiveNumbers. This also includes: more flexible cascaded validation of contai

beanvalidation.org

 

 

 

🍫사용해보기

 

1. dependecies 추가

 

- gradle

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

- Maven

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

 

 

 

2. 정규식을 사용하는 객체 (Vo)

package com.example.validation.dto;

import javax.validation.constraints.*;

public class User {
    @NotBlank(message = "이름을 확인해주세요.")
    private String name;
    @Min(value = 10, message = "나이를 확인해주세요.")
    private int age;
    @Email(message = "이메일 형식을 확인해주세요.")
    private String email;
    @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$",message = "핸드폰 번호 양식과 맞지 않습니다. ex:010-0000-0000")
    private String phoneNumber;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                ", phoneNumber='" + phoneNumber + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

 

 

 

3. 정규식을 받는 곳에서 @Valid 어노테이션 선언 

@Valid 어노테이션을 받은 객체는 그 안에 validation에서 사용하는 어노테이션들을 검사해서 받아온 값이 정규식과 일치 하지 않은면 에러를 표시한다. 

 

@RestController
@RequestMapping("/api")
public class ApiController {
    @PostMapping("/user")
    public User user(@Valid @RequestBody User user){
        System.out.println(user);
        return user;

    }
}

 

 

4. Validation 결과를  BindingResult로 받아 에러 메시지를 출력할 수 있다.

package com.example.validation.controller;

import com.example.validation.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
@RequestMapping("/api")
public class ApiController {
    @PostMapping("/user")
    public ResponseEntity user(@Valid @RequestBody User user, BindingResult bindingResult){

        if(bindingResult.hasErrors()){
            StringBuilder sb = new StringBuilder();
            bindingResult.getAllErrors().forEach(objectError -> {
                //오브젝트의 에러를 받아서.
                    //어떤 필드의 에러인지 오브젝트 에러를 형변환하여 넣어준다.
                    // 메시지를 통해 에러의 내용도 알수 있다.
                FieldError field = (FieldError) objectError;
                String message = field.getDefaultMessage();

                System.out.println("필드 :" + 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);
    }
}

- 결과 이미지

 

 

profile

minlog

@jimin-log

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!