스토리-1: 스케줄 정리 프로그램을 이용해서 스케줄 정리 해볼까!
@Getter
public class CreateScheduleRequest {
private String task; // 스케줄
private String name; // 작성자 이름
private Long authorId; // 작성자 ID
private String password; // 작성글 PW
}
데이터를 받아오는 DTO를 생성했다. 스케줄 입력란 OK, 작성자 이름 OK 등등 다 OK!
스토리-2: 아니 실수로 스케줄 입력안하고 등록했네.. 삭제하기 귀찮아
결과는 사용자도 불편하고 필요없는 데이터로 서버의 과부하도 일어난다.
그러면? 애초에 입력할때 조건을 주자!! 유효성 검사
유효성 검사는 클라이언트가 전송한 데이터가 서버의 요구 사항을 충족하는지를 확인하는 과정이다.
유효성 검사는 서버의 스트레스를 줄이고, 고객 경험을 향상시키는 중요한 요소다.
올바른 데이터 입력을 유도함으로써 시스템의 부하를 줄이고, 원활한 운영을 가능하게 만든다.
@ControllerAdvice를 사용하여 모든 컨트롤러에서 발생하는 유효성 검사 예외를 중앙 집중식으로 처리하는 방법.
아래는 GlobalExceptionHandler 클래스를 사용하여 유효성 검사 실패 시 적절한 응답을 클라이언트에게 반환하는 방법.
package com.example.schedule.exception;
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 java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
}
{
"task": "Task cannot be empty",
"name": "Name cannot be empty",
"password": "Password cannot be empty"
}
DTO 클래스에 @NotBlank, @Size, @Pattern 등의 어노테이션을 사용하여 필드에 대한 유효성 검사를 설정.
@NotBlank
@NotEmpty
@Pattern(regexp=, message=)
@Size(min=, max=)
아래는 유효성 검사 어노테이션을 사용해 필드에 대한 조건 부여한 방법
@Getter
public class CreateScheduleRequest {
@NotBlank(message = "Task cannot be empty") // 작업 필드 유효성 검사
@Size(max = 100, message = "Task must be 100 characters or less") // 작업 필드 최대 길이 검사
private String task;
@NotBlank(message = "Name cannot be empty") // 이름 필드 유효성 검사
@Size(max = 10, message = "Name must be 10 characters or less") // 이름 필드 최대 길이 검사
private String name;
private Long authorId; // 작성자 ID
@NotBlank(message = "Password cannot be empty") // 비밀번호 필드 유효성 검사
@Size(min = 6, max = 20, message = "Password must be between 6 and 20 characters") // 비밀번호 길이 검사
private String password;
}
| 입력 예시 | 에러 메시지 |
|---|---|
| " " (빈 문자열) | "Task cannot be empty" |
| "This is a very long task description that exceeds the maximum limit of one hundred characters. It goes on and on without stopping!" | "Task must be 100 characters or less" |
방금 말한 내 스토리로 유효성 검사가 왜 그렇게 중요한지 모를 수도 있다. 지금 편하자고 나중에 고생한다.. 일단 유효성 검사는 단순히 데이터의 정확성을 확인하는 과정이 아니라, 사용자의 경험을 향상시키고, 시스템의 신뢰성을 높이는 중요한 역할을 한다는 걸 항상 기억해두자.
1. @Vaildated 어노테이션 사용
DTO 클래스에 유효성 검사 어노테이션(예: @NotBlank, @Size)을 추가하여 각 필드에 대한 규칙을 정의.
클라이언트가 잘못된 데이터를 입력했을 때 즉각적으로 피드백을 제공하여 데이터의 정확성을 보장.
코드가 깔끔해지고, 각 필드의 유효성 규칙이 명확하게 드러난다.
2. 글로벌 예외 핸들러 생성
@ControllerAdvice를 사용하여 글로벌 예외 핸들러 클래스를 생성.
@ExceptionHandler를 사용하여 MethodArgumentNotValidException을 처리하고, 유효성 검사 실패에 대한 에러 메시지를 JSON 형식으로 반환.
모든 컨트롤러에서 발생하는 유효성 검사 오류를 한 곳에서 처리할 수 있어 코드 중복을 줄이고 유지보수를 용이.
클라이언트에게 일관된 형식의 오류 응답을 제공하여 사용자 경험을 향상.