LUMI_dev

Validation #1. Validation 검증 과정 (★프로그래밍의 가장 중요한 부분) 본문

스파르타 코딩 클럽 | 자바 심화 과정/Spring Master (숙련 주차)

Validation #1. Validation 검증 과정 (★프로그래밍의 가장 중요한 부분)

luminous_dev 2025. 2. 7. 04:48

Java는 null 값에 대한 접근에 대해 NullPointerException 오류가 발행하기 때문에 이러한 부분을 예방

Spring은 null 확인 뿐 아니라 문자의 길이 측정과 같은 다른 검증 과정도 쉽게 처리할 수 있도록 Bean Validation 제공

 

Bean Validation

어노테이션
내용
@NotNull
null 불가
@NotEmpty
null, “” 불가
@NotBlank
null, “”. “ “ 불가
@Size
문자 길이 측정
@Max
최대값
@Min
최소값
@Positive
양수
@Negative
음수
@Email
E-mail 형식
@Pattern
정규 표현식

 

 

프로젝트 설정 

build.gradle에 추가

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

Validation 적용

 

1. ProductRequestDto

package com.sparta.springauth.dto;

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

 

2. Valid 를 쓰고자하는  컨트롤러에 @Valid 어노테이션 추가 

ProductController

package com.sparta.springauth.controller;

import com.sparta.springauth.dto.ProductRequestDto;
import com.sparta.springauth.entity.User;
import com.sparta.springauth.entity.UserRoleEnum;
import com.sparta.springauth.security.UserDetailsImpl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

//Filter에서 user Request 객체에 넣은 거 받아와볼 것임
@Controller
@RequestMapping("/api")
public class ProductController {

    @GetMapping("/products")
    public String getProducts(@AuthenticationPrincipal UserDetailsImpl userDetails) {

        //Authentication의 Principle -> Principle에 UserDetail 들어감 -> 그걸 @AuthenticationPrincipal로 가져옴
        User user = userDetails.getUser(); //UserDetailsServiceImpl에서 UserDetailsImpl에 user을 넘겨서 저장된 user 가져오기
        System.out.println("user.getUsername() = " + user.getUsername());
        System.out.println("user.getEmail() = " + user.getEmail());
        return "redirect:/";
    }

    //Secured 테스트
    @Secured(UserRoleEnum.Authority.ADMIN) // 관리자용
    @GetMapping("/products/secured")
    public String getProductsByAdmin(@AuthenticationPrincipal UserDetailsImpl userDetails) {
        System.out.println("userDetails.getUsername() = " + userDetails.getUsername());
        for (GrantedAuthority authority : userDetails.getAuthorities()) {
            System.out.println("authority.getAuthority() = " + authority.getAuthority());
        }

        return "redirect:/";
    }

    @PostMapping("/validation")
    @ResponseBody
    public ProductRequestDto testValid(@RequestBody @Valid ProductRequestDto requestDto) {
        //데이터를 Body에 JSON 형식으로 받아올 것임 (@RequestBody 붙여줌)
        return requestDto;
    }
}

 

 

POSTMAN으로 테스트 

Body부분에는 아래 JSON 데이터 넣기 

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

 

 

근데 deny될 것임

다른 브라우저의 쿠키를 POSTMAN이 못 가져오므로  

 

프로젝트를 실행한 창에서 쿠키 더블클릭 _ 복사 

 

 

 

이때 전달한 json에 blank가 있으면 Dto의 @NotBlank가 실행되는 형식 ..