목차
요구사항
설명
- ✅ 유효성 검사
- 잘못된 입력이나 요청을 미리 방지할 수 있습니다.
- 데이터의 무결성을 보장하고 애플리케이션의 예측 가능성을 높여줍니다.
- Spring에서 제공하는 @Valid 어노테이션을 이용할 수 있습니다.
조건
- ✅ 할일은 최대 200자 이내로 제한, 필수값 처리
- ✅ 비밀번호는 필수값 처리
- ✅ 담당자의 이메일 정보가 형식에 맞는지 확인
요구 구현
ScheduleController
@RestController
@RequestMapping("/schedules")
public class ScheduleController {
private final ScheduleService scheduleService;
public ScheduleController(ScheduleService scheduleService) {
this.scheduleService = scheduleService;
}
@PostMapping
public ResponseEntity<ScheduleResponseDto> createSchedule(@RequestBody @Valid ScheduleRequestDto requestDto) {
return new ResponseEntity<>(scheduleService.saveSchedule(requestDto), HttpStatus.CREATED);
}
// 다른 메서드들 제외
}
- @RequestBody @Valid ScheduleRequestDto requestDto : `ScheduleRequestDto`에서 유효성 검증 어노테이션들(`@NotNull`, `@Size` 등)을 작동시키기 위해서 `@Valid`를 붙였습니다.
ScheduleRequestDto
@Getter
public class ScheduleRequestDto {
@NotNull(message = "사용자 Id는 필수 입니다.")
private Long userId;
@Size(max=200, message = "할 일은 200자 내여야 합니다.")
@NotNull(message = "할 일은 필수 입니다.")
private String toDoContent;
}
- `@NotNull`, `@Size` 어노테이션을 붙이면, 해당 필드에 유효성 위반시 `MethodArgumentNotValidException` 오류를 던집니다.
- `@NotNull` : 해당 값에 `null` 값이 들어오면 예외처리를 해줍니다.
- `@Size` : 해당 값에 max보다 큰 값이 들어오거나 min보다 작은 값이 들어오면 예외처리를 해줍니다.
- message 설정을 통해 예외처리 시, 보내고 싶은 message를 지정할 수 있습니다.
UserController
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<UserResponseDto> createUser(@RequestBody @Valid UserRequestDto requestDto) {
return new ResponseEntity<>(userService.saveUser(requestDto), HttpStatus.CREATED);
}
...
}
- @RequestBody @Valid UserRequestDto requestDto : `UserRequestDto`에서 유효성 검증 어노테이션들(`Email` 등)을 작동시키기 위해서 `@Valid`를 붙였습니다.
UserRequestDto
@Getter
public class UserRequestDto {
@Email(message = "올바른 형식의 이메일 주소가 아닙니다.")
private String email;
private String userName;
}
- `@Email` 어노테이션을 붙이면, 해당 필드에 유효성 위반시 `MethodArgumentNotValidException` 오류를 던집니다.
- `@NotNull` : 해당 값에 `null` 값이 들어오면 예외처리를 해줍니다.
- message 설정을 통해 예외처리 시, 보내고 싶은 message를 지정할 수 있습니다.
GlobalExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler {
....
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleMethodArgumentNotValidException (
MethodArgumentNotValidException ex,
HttpServletRequest request) {
Map<String, Object> response = new HashMap<>();
response.put("timestamp", LocalDateTime.now());
response.put("status", ex.getStatusCode().value());
String errorMessage = ex.getBindingResult().getFieldErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", "));
response.put("message", errorMessage);
response.put("path", request.getRequestURI());
return new ResponseEntity<>(response, ex.getStatusCode());
}
}
- 유효성 검증 어노테이션에서 발생하는 예외를 공통으로 처리하는 메서드입니다.
(예외처리는 했지만, 보여지는건 예외 발생했을 때랑 비슷해보이게 커스텀하였습니다.)
❗유효성 검증 어노테이션은 기본적으로 제공하는 예외처리가 있습니다.
(커스텀으로 만들어보고싶어서 진행하였습니다. 필수 ❌)
회고
1. @Valid에 대해 처음 겪어보다보니 사용하는게 익숙하지 않았습니다.
❗트러블 슈팅으로 작성하려다, 처음 사용하는 것이기 때문에 회고를 통해 내용 정리를 진행하였습니다.
@Valid란?
- `javax.validaton.valid`(Java EE) 또는 `jakarta.validation.valid`(Jakarta EE) 패키지의 어노테이션입니다.
- `@Valid`는 자바 빈 검증(Bean Validation)을 트리거(trigger)하는 어노테이션으로, 객체의 필드들이 적절하게 설정되어 있는지 검사합니다.
- 객체 내부의 필드에 붙은 유효성 검증 어노테이션들(@NotNull, @Size, @Email, 등)을 자동으로 검사합니다.
- `@Valid` 어노테이션이 없으면, 아무리 유효성 검증 어노테이션을 붙여도 검증이 수행되지 않습니다.
내부적으로 동작
- Spring은 `@Valid`를 감지하고, JSR-300 Bean Validation API (Hibernate Validator가 대표 구현체)를 사용하며 DTO 필드들을 검사합니다.
- 유효성 위반 시 `MethodArgumentNotValidException`을 통해 예외를 던집니다.
유효성 검증 어노테이션 종류
어노테이션 | 설명 |
@NotNull | null이 아니어야 함 |
@NotEmpty | null 또는 ""(빈 문자열)이 아니어야 함 (문자열, 컬렉션, 배열 등) |
@NotBlank | 공백 문자만 있어도 안 됨 (" "도 유효하지 않음) |
@Size(min=, max=) | 문자열, 배열, 컬렉션의 길이 또는 크기 제한 |
@Min(value) | 숫자의 최소값 제한 |
@Max(value) | 숫자의 최대값 제한 |
@Positive | 양수만 허용 (> 0) |
@PositiveOrZero | 양수 또는 0 허용 (>= 0) |
@Negative | 음수만 허용 (< 0) |
@NegativeOrZero | 음수 또는 0 허용 (<= 0) |
이메일 형식이 맞는지 검증 | |
@Pattern(regexp = "") | 정규식으로 형식 지정 (예: 전화번호, 비밀번호 조건 등) |
@AssertTrue | boolean이 true여야 함 |
@AssertFalse | boolean이 false여야 함 |
@Past | 현재보다 과거여야 함 |
@PastOrPresent | 과거 또는 현재여야 함 |
@Future | 현재보다 미래여야 함 |
@FutureOrPresent | 미래 또는 현재여야 함 |
트러블 슈팅
1. 유효성 검증 어노테이션에 대한 오류 출력 시, 사용자 message 출력 안되는 오류
✅ 유효성 검증 어노테이션은 공통 예외처리로 따로 커스텀하여 처리하지 않아도 기본적으로 예외처리를 진행합니다.
따라서 커스텀 예외처리 없이, 그냥 사용하면 아래에서와 같이 예외처리가 되어 응답받습니다.
설명 & 문제
userId가 null이거나 toDoContent가 null, size가 200이 넘어가면 예외처리가 발생합니다.
userId를 추가하지 않자, `@Notnull` 어노테이션으로 인해 예외처리가 발생하였습니다.
하지만 여기서 문제 ❗, 내가 설정한 message가 보이지 않는 것을 알 수 있습니다.
해결 방법
Spring Boot의 기본 동작은 예외를 `BasicErrorController`가 처리합니다. 하지만 `message`, `errors` 필드를 포함시키려면 `application properties`에서 옵션을 켜야합니다.
server.error.include-message=always를 넣어주시면 됩니다.
사용자 설정 message가 정상적으로 출력됩니다.
'Project' 카테고리의 다른 글
[Project] Lv_1 스케줄 프로젝트(심화) (0) | 2025.05.19 |
---|---|
[Project] Lv_0 스케줄 프로젝트(심화) (0) | 2025.05.19 |
[Project] Lv_5 스케줄 프로젝트 (0) | 2025.05.13 |
[Project] Lv_4 스케줄 프로젝트 (2) | 2025.05.12 |
[Project] Lv_3 스케줄 프로젝트 (2) | 2025.05.12 |