Spring

Spring 숙련 10 (Validation) (Validation 예외처리)

sehunbang 2024. 1. 26. 16:38

Validation이란?

 

프로그래밍을 하는데에 있어서 가장 중요한 부분 중 하나입니다.

Java는 null 값에 대한 접근에 대해 NullPointerException 오류가 발행하기 때문에

이 부분을 예방하기 위해 Validation 즉, 검증 과정이 필요합니다.

 

Spring에서는 null 확인 뿐 아니라

문자의 길이 측정과 같은 다른 검증 과정도 쉽게 처리할 수 있도록

Bean Validation 제공하고 있습니다.

 

build.gradle 에 Bean Validation 라이브러리 추가.

 

 

 

Bean Validation

편하게 사용할 수 있는 애너테이션을 제공 해줍니다

 

@NotNull : null 불가 

@NotEmpty  :  null, “” 불가 

@NotBlank :  null, “”. “ “ 불가 

@Size  :  문자 길이 측정 

@Max  :  최대값 

@Min   :  최소값 

@Positive  :  양수 

@Negative  :  음수 

@Email  :  E-mail 형식 

@Pattern  :  정규 표현식

 

 

 

Validation 적용

New DTO class

ProductRequestDto.java

import jakarta.validation.constraints.*;
@Getter
public class ProductRequestDto {
    @NotBlank
    private String name;
    @Email
    private String email;
    @Positive(message = "양수만 가능합니다.")
    private int price;
    @Negative(message = "음수만 가능합니다.")
    private int discount;
    @Size(min=2, max=10)
    private String link;
    @Max(10)
    private int max;
    @Min(2)
    private int min;
}

 

 

@Valid 를 달아야 내사 validation 을 실행 시키고 싶은 Dto 를 validation  을 할수 있음.

Bean Validation을 적용한 해당 Object validation 실행

컨트롤러에 추가.

@PostMapping("/validation")
@ResponseBody
public ProductRequestDto testValid(@RequestBody @Valid ProductRequestDto requestDto) {
    return requestDto;
}

 

 

POST Man 으로 테스트.

json body 로 테스트:

{ "name" : "Robbie", "email" : "Robbie@gmail.com", "price" : 1234, "discount" : -1234, "link" : "54321", "max" : 10, "min" : 2 }

 

하면 거부 당함..........

 

왜냐면 쿠키가 없기 때문이다.

 

웹 브라우저 에 받은 쿠키를 복사(더블 클릭 + 복사) 해서

 

Post Man cookies 에 넣어 준다.

 

 

만약 모든 validation 이 맞을 경우 :

 

 

만약 validation 일 틀릴 경우 (Execption):

2024-01-26T16:18:21.677+09:00  WARN 7408  ............ [name]]; default message [공백일 수 없습니다]] ]

 

 

 

Validation 예외처리

 

SignUpRequestDto.java 을 Validation 들 을 추가 하겠습니다.

public class SignupRequestDto {
    @NotBlank
    private String username;
    @NotBlank
    private String password;
    @Email
    @NotBlank
    private String email;
    private boolean admin = false;
    private String adminToken = "";
}

 

Controller 에 있는 SignUp 코드도 변경

@Slf4j
@Controller
@RequestMapping("/api")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/user/login-page")
    public String loginPage() {
        return "login";
    }

    @GetMapping("/user/signup")
    public String signupPage() {
        return "signup";
    }

    @PostMapping("/user/signup")
    public String signup(@Valid SignupRequestDto requestDto, BindingResult bindingResult) {
        // Validation 예외처리
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        if(fieldErrors.size() > 0) {
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage());
            }
            return "redirect:/api/user/signup";
        }

        userService.signup(requestDto);

        return "redirect:/api/user/login-page";
    }
}

 

BindingResult bindingResult 객체에 오류가 담김

 

그러면 

List<FieldError> fieldErrors = bindingResult.getFieldErrors();

안에 넣은 다음에

에러가 있으면 (fieldErrors 사이즈가 0 보다크면)

반복문 :      

for (FieldError fieldError : bindingResult.getFieldErrors()) {
        log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage());
 }

로  에러들 표시하고

 

return "redirect:/api/user/signup";

다시 Signup 페이지로 돌려 보냅니다.