Spring-Validation

이호영·2022년 3월 5일
0

Spring

목록 보기
9/18

Validation이란 프로그래밍에서 가장 중요한 부분으로
특히 java에서 null값에 접근 하려 할때 null pointer Exception이 발생함으로 이 부분을 방지하기 위해 미리 검증하는 과정을 말합니다.

관련 Annotation

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

예제 코드

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;
import java.io.ObjectInputStream;

@RestController
@RequestMapping("/api")
public class ApiController {
    @PostMapping("/user")
    public ResponseEntity user(@Valid @RequestBody User user, BindingResult bindingResult){
        //@Valid가 붙은 객체는 그안에 @Email같은 Annotation을 검사하여 값을 검증
        //@BindlingResult:  @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);
    }
}
package com.example.validation.dto;

import jdk.jfr.Experimental;

import javax.validation.constraints.*;

public class User {
    @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 = "핸드폰 번호 양식과 맞지 않습니다.")
    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) {
        PhoneNumber = phoneNumber;
    }

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

Custom validation

package com.example.validation.validator;

import com.example.validation.annotation.YearMonth;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class YearMonthValidator implements ConstraintValidator<YearMonth, String> {

    private String pattern;

    @Override
    public void initialize(YearMonth constraintAnnotation) {
    this.pattern=constraintAnnotation.pattern();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        //yyyyMMdd

        try {
            LocalDate localDate = LocalDate.parse(value+"01", DateTimeFormatter.ofPattern(this.pattern));
        }catch (Exception e){
            return false;
        }
        return true;

    }
}
package com.example.validation.dto;

import com.example.validation.annotation.YearMonth;
import jdk.jfr.Experimental;
import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class User {
    @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 = "핸드폰 번호 양식과 맞지 않습니다.")
    private String PhoneNumber;

    @YearMonth
    private String reqYearMonth; //yyyymm

    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) {
        PhoneNumber = phoneNumber;
    }

    public String getReqYearMonth() {
        return reqYearMonth;
    }

    public void setReqYearMonth(String reqYearMonth) {
        this.reqYearMonth = reqYearMonth;
    }

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

YearMonth Annotation

package com.example.validation.annotation;

import com.example.validation.validator.YearMonthValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@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 "yyyyMMdd";

}

0개의 댓글