오늘 배운 것
- validation
- Bean Validation 종류
- Bean Validation 적용
- Validation 예외 처리
Validation이란
백엔드 서버에서 입력 값을 검증해야 할 때가 있습니다.
예를 들어 Java에서는 null 값이 있어서 입력 값으로 null 값이 들어왔을 때 제대로 된 처리를 하지 않으면 NullPointException이 발생합니다.
이런 NullPointException을 예방하기 위해서 Validation 즉 검증 과정이 필요하다.
또 비즈니스 요구사항으로 'id는 소문자, 숫자로만 구성되고 6~10자로 구성되어야 한다' 이런 것이 있을 수 있습니다.
이럴 때 입력 값으로 들어온 id가 비즈니스 요구 사항에 맞는지 검증 과정이 필요하다.
이전에는 이런 검증은 프론트엔드에서 다 하기 때문에 백엔드에서는 또 할 필요가 있나 싶은 생각이 있었다.
그런데 백엔드에서도 한번 더 하는 것이 좋다고 한다.
Bean Validation 종류
Spring에서는 Validation을 쉽게 적용할 수 있게, 간편하게 사용할 수 있는 여러 annotation을 제공한다.
이런 annotation들이 없다면 직접 각 값들에 대한 검증 로직을 작성해야 하는 번거로움이 있다.
@NotNull | null 불가 | @Size | 문자열, 컬렉션, 배열, 맵 등의 크기 |
@NotEmpty | null, "" 불가 | @Positive | 양수 |
@NotBlank | null, "", " " 불가 | @Negative | 음수 |
@Max | 최대 값 | Email 형식 | |
@Min | 최소 값 | @Pattern | 정규 표현식 |
위의 annotation 말고도 굉장히 많은 검증을 위한 annotation들이 있다.
이런 annotation을 entity나 dto의 필드에 붙여서 해당 필드에 대해서 검증을 하는 것이다.
다양한 annotation들은 아래에서 확인해 볼 수 있다.
https://jakarta.ee/specifications/bean-validation/3.0/apidocs/
Overview (Jakarta Bean Validation API 3.0.0)
jakarta.ee
Bean Validation 적용
Bean Validation을 프로젝트에 적용해보자.
우선 build.gradle에 Validation dependency를 추가해줘야 한다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
그리고 dto의 필드에 bean validation annotation들을 추가하는 것이다.
import jakarta.validation.constraints.*;
import lombok.Getter;
@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;
}
이렇게 하면 끝이 아니다.
Bean Validation 기능을 수행하려면 @Valid라는 annotation을 사용해야 한다.
Bean Validation이 적용된 객체에 Bean Validation 기능 수행하려면 파라미터에서 @Valid를 붙여주면 된다.
@PostMapping("/validation")
@ResponseBody
public ProductRequestDto testValid(@RequestBody @Valid ProductRequestDto requestDto) {
return requestDto;
}
꼭 Controller에서만 하는 것이 아니고 Service에서도 아래와 같이 사용할 수 있다.
public Product createProduct(@Valid ProductRequestDto requestDto){
...
}
이렇게 메서드의 파라미터로 넘어오는 객체에 @Valid를 붙여 해당 객체에 적용된 Bean Validation을 수행하는 것이다.
Bean Validation이 실패하면 예외가 발생하고 메서드가 수행되지 않는다.
Validation 예외 처리
Bean Validation이 실패하면 예외가 발생한다.
이때 Bean Validation이 실패했을 때 예외 처리를 따로 할 수 있다.
바로 BindingResult를 사용하는 방법이다.
예외가 발생하면 BindingResult 객체에 오류에 대한 정보가 담긴다.
이 BindingResult는 파라미터로 받아올 수 있다.
@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.getFieldErrors() 메서드로 오류가 난 필드들을 하나씩 가지고 올 수 있다.
- 발생한 오류들에 대한 정보가 담긴 List<FieldError> 리스트를 가져온다.
- getField와 getDefaultMessage 메서드로 필드와 지정한 에러 메시지 가져올 수 있다.
- 위의 코드는 예외 처리로 회원 가입 페이지로 redirect한 것이다.
정리
입력 값을 검증하거나 DB에 Entity를 저장할 때 저장된 값을 검증할 필요가 있다.
프론트엔드에서 할 수도 있지만 백엔드에서 한번 더 하는 것이 좋다.
다양한 Bean Validation annotation과 Bean Validation 기능을 수행하는 @Valid annotation으로 검증할 수 있다.
'TIL' 카테고리의 다른 글
24.09.06 TIL - CSRF (0) | 2024.09.08 |
---|---|
24.09.05 TIL - Effective Java Item 63 (1) | 2024.09.08 |
24.09.03 TIL - Spring Security Login with JWT (0) | 2024.09.08 |
24.09.02 TIL - Spring Security 동작 원리 (0) | 2024.09.07 |
24.08.28 - JWT in Spring (6) | 2024.08.30 |