유효성 검증

이경영·2022년 10월 18일
0

스프링부트2

목록 보기
15/19
post-custom-banner

유효성 검사란?

  • 서비스의 비즈니스 로직이 올바르게 동작하기 위해 사용되는 데이터에 대한 사전 검증하는 작업이 필요함
  • 유효성 검사 혹은 데이터 검증이라고 부르는데, 흔히 Validation이라고 부름
  • 데이터의 검증은 여러 계층에서 발생하는 흔한 작업
  • Validation은 들어오는 데이터에 대해 의도한 형식의 값이 제대로 들어오는지 체크하는 과정을 뜻함.

일반적인 validation의 문제점

일반적인 어플리케이션에서 사용되던 validation 방식은 몇가지 문제가 존재

  • 어플리케이션 전체적으로 분산되어 존재
  • 코드의 중복이 심함 (코드 복잡)
  • 비즈니스 로직에 섞여있어 검사 로직 추적이 어려움

Bean validation / Hibernate Validator

앞서 나온 문제를 해결하기 위해 Java에서 2009년부터 Bean Validation이라는 데이터 유효성 검사 프레임워크를 제공
Bean Validation은 어노테이션을 통해 다양한 데이터를 검증할 수 있게 기능을 제공

Hibernate Validator는 Bean Validation 명세에 대한 구현체
Spring Boot의 유효성 검사 표준은 Hibernate Validator를 채택
이전 버전의 SpringBoot에서는 starter-web에 validation이 포함되어 있었지만, 2.3버전부터 starter-validation을 추가해야 함

Validation 관련 어노테이션

---실습---

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

ProductDto.java

package com.example.testproject.data.dto;

import com.example.testproject.data.entity.ProductEntity;
import lombok.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class ProductDto {
    //@ize(min=8, max=8)
    @NotNull
    private String productId;
    @NotNull
    private String productName;
    @NotNull
    @Min(value=500)
    @Max(value=300000)
    private int productPrice;
    @NotNull
    @Min(value=0)
    @Max(value=9999)
    private int productStock;

    public ProductEntity toEntity(){
        return ProductEntity.builder()
                .productId(productId)
                .productName(productName)
                .productPrice(productPrice)
                .productStock(productStock)
                .build();

    }

}
  // http://localhost:8080/api/v1/product-api/product
    @PostMapping(value = "/product")
    public ResponseEntity<ProductDto> createProduct(@RequestBody ProductDto productDto) {

        String productId = productDto.getProductId();
        String productName = productDto.getProductName();
        int productPrice = productDto.getProductPrice();
        int productStock = productDto.getProductStock();

        ProductDto response=productService.saveProduct(productId,productName,productPrice,productStock);

        LOGGER.info(
                "[createProduct] Response >> productId : {} , productName : {} , productPrice : {}, productStock : {}",
                response.getProductId(), response.getProductName(), response.getProductPrice(), response.getProductStock()
        );
        return ResponseEntity.status(HttpStatus.OK).body(response);
    }

결과

[2022-10-19 01:04:50.359] [INFO ] [http-nio-8081-exec-8] c.e.t.c.ProductController [createProduct] Response >> productId : string , productName : string , productPrice : -800, productStock : 0

swagger-ui로 확인했을때 응답이 200대로 오류가 전혀 발생하지 않았음을 알 수 있음.

  • DB에도 -800값이 들어와있음

=> 앞서 설정한 제약조건들이 적용되지 않았음

   // http://localhost:8080/api/v1/product-api/product
    @PostMapping(value = "/product")
    public ResponseEntity<ProductDto> createProduct(@Valid @RequestBody ProductDto productDto) { //****이부분에 어노테이션 Valid 붙여줬음****

        String productId = productDto.getProductId();
        String productName = productDto.getProductName();
        int productPrice = productDto.getProductPrice();
        int productStock = productDto.getProductStock();

        ProductDto response=productService.saveProduct(productId,productName,productPrice,productStock);

        LOGGER.info(
                "[createProduct] Response >> productId : {} , productName : {} , productPrice : {}, productStock : {}",
                response.getProductId(), response.getProductName(), response.getProductPrice(), response.getProductStock()
        );
        return ResponseEntity.status(HttpStatus.OK).body(response);
    }

결과 : 이제는 400대 에러 발생함

[2022-10-19 01:11:36.402] [WARN ] [http-nio-8081-exec-8] o.s.w.s.m.s.DefaultHandlerExceptionResolver Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.example.testproject.data.dto.ProductDto> com.example.testproject.controller.ProductController.createProduct(com.example.testproject.data.dto.ProductDto): [Field error in object 'productDto' on field 'productPrice': rejected value [-800]; codes [Min.productDto.productPrice,Min.productPrice,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [productDto.productPrice,productPrice]; arguments []; default message [productPrice],500]; default message [500 이상이어야 합니다]] ]

//참고 코드
        //Validation code Example
        if (productDto.getProductId().equals("") | productDto.getProductId().isEmpty()){
            LOGGER.error("[createProduct] failed Response :: productId is Empty");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(productDto);
        }
profile
꾸준히
post-custom-banner

0개의 댓글