오티스의개발일기

[SPRING BOOT] spring boot javax validation 을 사용하여 정규식 사용하기 + exception Handler를 활용해 로그 및 비지니스로직 처리 본문

개발/spring boot

[SPRING BOOT] spring boot javax validation 을 사용하여 정규식 사용하기 + exception Handler를 활용해 로그 및 비지니스로직 처리

안되면 될때까지.. 2022. 12. 29. 11:26
728x90

 

 

 

오늘은 spring boot validation을 활용해 controller 를 통해 들어오는 변수들의 정규식을 컨트롤 해볼것이다.

 

일단 라이브러리를 살펴보자

 

 

수많은 @어노테이션을 볼수있고

생각보다 이해하기 쉽게 이름이 네이밍 되어있다

 

이곳의 주요 어노테이션을 대략적으로 설명해보겠다.

 

@Size : 문자 길이 조건

@NotNull : null 값 불가

@NotEmpty : @NotNull + ""값 불가

@NotBlank : @NotEmpty + " " 값 불가

 

@Past : 과거 날짜

@PastOrPresent : @Past + 오늘 날짜

@Future : 미래 날짜

@FutureOrPresent : @Future + 오늘 날짜

 

@Pattern : 정규식을 통한 조건

 

@Email : 이메일 정규식

 

@Max : 최대값 조건 설정

@Min : 최소값 조건 설정

@AssertTrue / AssertFalse : 참/거짓 조건 설정

 

@Valid : 해당 객체의 유효성검사 

 

 

대략적인 흐름은 이러하다

1. 컨트롤러로 api 요청

2. dto의 미리 등록된 규칙들 검사

3. 규칙에 실패했을시 MethodArgumentNotValidException 이 발생

4. 만들어놓은 핸들러에 이벤트 실행

5. 에러코드 및 메시지를 response

 

한번 만들어보자

 

 

 

 

만들 파일들 목록

 

1. 파라미터로 받을 dto

2. 유효성 검사 @Valid 를 등록할 컨트롤러

3. excptionHandler 생성

 

 

# 0 . 파일 구조

 

 

 

 

 

 

# 1 .  RequestUserRegisterDto.java 생성

 

package com.example.backend.dto.user.request;

import com.example.backend.domain.User;
import lombok.Data;
import org.springframework.lang.Nullable;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;

@Data
public class RequestUserRegisterDto {

    @NotBlank(message = "이름을 입력해주세요")
    private String userName; // 이름

    @NotBlank(message = "이메일을 입력해주세요.")
    @Email(message = "정확한 이메일을 입력해주세요")
    private String email; // 이메일

    @Nullable
    private String provider; // 로그인한 sns 브랜드명 예) google

    @Nullable
    private String providerId; // 로그인한 sns의 회원 고유번호 예)asdAKSDJjwndjicIAI2314

    @Nullable
    private String phone;

    public User toEntity () {
        return User.builder()
                .userName(userName)
                .email(email)
                .provider(provider)
                .providerId(providerId)
                .phone(phone)
                .build();
    }
}

 

이제 이 dto에서 정규식에 실패했을시 

MethodArgumentNotValidException 라는 예외가 발생한다

우리는 그걸 캐치해서 로직을 처리할 것이다.

 

 

 

 

# 2 .  UserController.java 생성

package com.example.backend.controller;

import com.example.backend.common.exception.CustomApiException;
import com.example.backend.dto.CMRespDto;
import com.example.backend.dto.user.request.RequestUserRegisterDto;
import com.example.backend.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequiredArgsConstructor
@CrossOrigin(origins = {"*"})
@RequestMapping("/api/user")
public class UserController {

    private final UserService userService;
    @PostMapping("/register")
    public CMRespDto<?> register (@Valid @RequestBody RequestUserRegisterDto requestUserRegisterDto) { 
        System.out.println("123");
        return new CMRespDto<>(200, "정상처리", null);
    }

//    @GetMapping("/hi")
//    public CMRespDto<?> hi (){
//        userService.register();
//        return new CMRespDto<>(200, "정상처리", null);
//    }
}

 

 

컨트롤러를 만들었다 저곳에있는 @Valid 를 꼭붙여줘야지 검사를 진행하니 잊지말고 붙여주길 바란다

 

 

 

 

 

 

 

# 3.  ValidationExceptionHandler.java 생성

 

package com.example.backend.common.handler;

import com.example.backend.common.aop.LogAdvice;
import com.example.backend.dto.CMRespDto;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
@RequiredArgsConstructor
public class ValidationExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(LogAdvice.class);
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> validationApiException(MethodArgumentNotValidException e, HttpServletRequest request) {
        logger.error("Request: {} {})", request.getMethod(), request.getRequestURL());
        return new ResponseEntity<>(
                new CMRespDto<>(
                        HttpStatus.BAD_REQUEST.value(),
                        e.getBindingResult().getAllErrors().get(0).getDefaultMessage(),
                        null),
                HttpStatus.BAD_REQUEST);
    }

}

 

이제 이곳에서 MethodArgumentNotValidException 예외가 발생시 이 핸들러가 동작하고

원하는 정보를 반환해줄것이다.

 

# 4 . CMRespDto.java

 

package com.example.backend.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor
@AllArgsConstructor
@Getter @Setter
public class CMRespDto<T> {
    private int code; 
    private String message;
    private T data;

}

 

 

 

자 이제 postman 을 활용하여 반환값을 확인해보자

 

 

 

3가지를 해볼건데

 

이메일 형식이 아닌 값을 보내볼것이고

notnull 에 빈값을 보내볼것이다

 

 

 

1. 이메일 형식을 안보냈을때

 

 

 

2. null 을 보냈을때

 

 

 

3. 정상 동작

 

 

이것으로 validation 포스팅을 마치도록하겠다.

 

728x90
Comments