백엔드/spring boot

@Valid 어노테이션

STUFIT 2023. 11. 8. 11:18
반응형

api를 만들 때, 서비스 부분에서 예외처리를 했었는데, nestjs 를 사용할때처럼 기본적으로 null값이나 blank를 자체적으로 exception 이 되도록 하는 방법은 없을까 생각하는 찰나에 @Valid 어노테이션에 대해 알게 되었다.

@Valid 어노테이션은 @Valid , @Validated 두가지가 존재하고, 이 두개의 어노테이션을 이용하면 내가 서비스에서 예외처리 코드를 만들지 않아도 null 또는 blank, 길이 등에 대해 오류가 발생하면 자체적으로 예외처리가 된다. 

아래에서 예제를 들어보겠다.
1. 디펜던시 추가

gradle 에 해당 디펜던시를 추가하여 어노테이션을 사용할 수 있도록 설정한다.

먼저, gradle에 해당 디펜던시를 추가한다.
implementation 'org.springframework.boot:spring-boot-starter-validation' // @Valid 어노테이션

2. DTO에 적용

보통 직접적으로 엔티티를 사용해서 인스턴스를 만들지 않고 DTO를 이용하니, 여기서는 DTO에서 @Valid 어노테이션을 사용하는 것을 예제로 하겠다.

package awesomebro.awesomebro_solo.dto.profile;

import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
public class ProfileCreateAndUpdateRequestDto {
    private String age;
    private String gender;
    private String introduce;
    private String nickname;
    @NotBlank(message = "핸드폰 번호를 입력해주세요.")
    @NotNull(message = "핸드폰 번호를 입력해주세요.")
    private String phoneNumber;
    @NotBlank(message = "프로필 사진을 입력해주세요.")
    @NotNull(message = "핸드폰 번호를 입력해주세요.")
    private String profilePicture;
}

위에서 보면 @NotBlank, @NotNull 이라는 어노테이션이 붙어있는데, 해당 부분이 추후 컨트롤러에 @Valid 어노테이션을 붙이면 예외처리가 활성화된다.

@Valid 어노테이션에서 사용가능한 어노테이션은 다음과 같다.

 

어노테이션 설명
@NotNull 필드 값이 null이 아니어야 함을 지정합니다. 
@NotEmpty 문자열이나 컬렉션이 비어 있지 않아야 함을 지정합니다.
@NotBlank 문자열에 공백, null 또는 빈 문자열이 아닌 실제 문자가 포함되어야 함을 지정합니다.
@Email 문자열이 이메일 형식에 맞아야 함을 지정합니다.
@Size 문자열, 컬렉션, 배열 등의 크기가 지정된 범위 내에 있어야 함을 지정합니다.
@Min 숫자 값이 지정된 최소값 이상이어야 함을 지정합니다.
@Max 숫자 값이 지정된 최대값 이하이어야 함을 지정합니다. 
@Positive 숫자 값이 양수여야 함을 지정합니다.   
@PositiveOrZero 숫자 값이 0 또는 양수여야 함을 지정합니다.     
@Negative 숫자 값이 음수여야 함을 지정합니다.          
@NegativeOrZero 숫자 값이 0 또는 음수여야 함을 지정합니다. 
@Past 날짜가 과거여야 함을 지정합니다.   
@PastOrPresent 날짜가 과거 또는 현재여야 함을 지정합니다.     
@Future 날짜가 미래여야 함을 지정합니다.          
@FutureOrPresent 날짜가 미래 또는 현재여야 함을 지정합니다. 
@Pattern 문자열이 정규 표현식과 일치해야 함을 지정합니다.   
@Digits 숫자가 지정된 정수 및 소수 자릿수를 넘지 않아야 함을 지정합니다
   


이러한 어노테이션들은 `javax.validation.constraints` 패키지에 포함되어 있으며, 클래스의 필드, 메소드 매개변수, 메소드 반환 값 등에 적용할 수 있습니다. `@Valid` 어노테이션은 이러한 검증을 활성화하는 데 사용됩니다. 예를 들어, 컨트롤러의 메소드 매개변수에 `@Valid`를 사용하여 요청 본문에 바인딩되는 객체의 검증을 활성화할 수 있습니다.

 

3. 컨트롤러에서 Valid 적용.

위에서 DTO에 원하는 예외처리 어노테이션을 붙인 후에는 컨트롤러에서 @Valid 어노테이션을 사용하여 검증처리 하도록 합니다.

package awesomebro.awesomebro_solo.profile.controller;

import awesomebro.awesomebro_solo.dto.profile.ProfileCreateAndUpdateRequestDto;
import awesomebro.awesomebro_solo.global.oauth2.CustomUserDetails;
import awesomebro.awesomebro_solo.profile.Profile;
import awesomebro.awesomebro_solo.profile.service.ProfileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/profile")
public class ProfileController {
    private final ProfileService profileService;


    @GetMapping("/sign-up")
    public String showProfileSetupForm(Model model) {
        model.addAttribute("profile", new Profile());
        return "sign-up";
    }

    @PatchMapping("/update")
    public String handleProfileSetup(@AuthenticationPrincipal CustomUserDetails customUserDetails,@Valid @RequestBody ProfileCreateAndUpdateRequestDto profileDto) {
        profileService.saveProfile(customUserDetails,profileDto);
        return "redirect:/dashboard"; // 성공 시 대시보드 또는 적절한 페이지로 리다이렉트
    }


}

handleProfileSetup 메서드를 보면 파라미터쪽에 @Valid 어노테이션이 있는데, 검증을 원하는 파라미터 앞에 @Valid 어노테이션을 붙이게 되면 해당 파라미터는 검증처리를 하게 됩니다.

반응형