본문 바로가기
Spring

Validation

by step 1 2021. 6. 19.
반응형

Validation이란 프로그래밍에 있어서 가장 필요한 부분이다. 특히 java에서는 null값에 대해서 접근하려고 할 때 null pointer exception이 발생 함으로, 이러한 부분을 방지 하기 위해서 미리 검증을 하는 과정을 Validation이라고 한다.

 

단순 코드 예제

    public void run(String account, String pw, int age){
        if (account == null || pw == null){
            return;
        }
        if (age == 0){
            return;
        }
        
        // 정상 처리할 logic
    }

 

  • 검증해야 할 값이 많은 경우 코드의 길이가 길어 진다.
  • 구현에 따라서 달라 질 수 있지만 Service Logic과의 분리가 필요 하다.
  • 흩어져 있는 경우 어디에서 검증을 하는지 알기 어려우며, 재사용의 한계가 있다.
  • 구현에 따라 달라질 수 있지만, 검증 Logic이 변경 되는 경우 테스트 코드 등 참조하는 클래스에서 Logic이 변경되어야 하는 부분이 발생 할 수 있다.

Validation 어노테이션

@Size 문자 길이 측정 Int Type 불가
@NotNull null 불가  
@NotEmpty null, "" 불가  
@NotBlank null, "", " " 불가  
@Past 과거 날짜  
@PastOrPresent 오늘이거나 과거 날짜  
@Future 미래 날짜  
@FutureOrPresent 오늘이거나 미래 날짜  
@Pattern 정규식 적용  
@Max 최대값  
@Min 최소값  
@AssertTrue / False 별도 Logic 적용  
@Valid 해당 object validation 실행  

gradle dependency

implementation 'org.springframework.boot:spring-boot-starter-validation'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.5.1'

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation

bean validation spec

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

 

핸드폰번호 정규식

"^\\d{2,3}-\\d{3,4}-\\d{4}$"

 

예제 

email 유효성 검사

DTO 생성(@Email 어노테이션을 사용하여 email 양식에 맞는지 확인)

package com.example.validation.dto;

import javax.validation.constraints.Email;

public class User {

    private String name;

    private int age;

    // @Email: e-mail 양식에 맞지않으면 에러발생
    @Email
    private String email;

    private String 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;
    }

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

controller (@Valid 어노테이션을 사용하여 해당 객체에 유효성 검사를 진행하기 위해 선언)

package com.example.validation.controller;

import com.example.validation.dto.User;
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 {
// @Valid: 유효성 검사를 하기위해 선언
    @PostMapping("/user")
    public User user(@Valid @RequestBody User user){
        System.out.println(user);

        return user;
    }
}

json

{
  "name": "홍길동",
  "age": 10,
  "email": "abc",
  "phoneNumber": "01022223333"
}

에러 발생

정상 처리

 

핸드폰 번호 유효성 검사 추가(정규식 사용)

// @Pattern: 정규식을 이용하여 핸드폰번호 데이터 체크    
    @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$")
    private String phoneNumber;

에러 발생

 

정상 처리

 

입력값 체크후 메시지 띄우는 방법(message 속성을 DTO 객체에 추가)

// @Pattern: 정규식을 이용하여 핸드폰번호 데이터 체크, messgae 속성을 이용해서 에러 발생시 메시지 처리
    @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "핸드폰 번호의 양식과 맞지 않습니다. 01x-xxx(x)-xxxx")
    private String phoneNumber;

 

controller 수정

 @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 = 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);
    }

BindingResult로 에러를 확인하고 에러발생시 어디서 에러발생하였는지(FieldError)

message를 어떻게 보여줄지 확인 후 return 값으로는 ResponseEntity값으로 반환한다.

 

에러발생

 

정상 처리

 

반응형

'Spring' 카테고리의 다른 글

Exception 처리  (0) 2021.06.19
Custom Validation  (0) 2021.06.19
Json으로 출력된 데이터 확인  (0) 2021.06.13
주요 어노테이션  (0) 2021.06.13
AOP  (0) 2021.06.13