개발/Spring
Validation
by BellOne4222
2024. 2. 19.
Validation
- 사용자 입력값에 있을지 모르는 오류를 처리하기 위해서
- 모든 입력단 앞에 방어 코드가 추가된다.
- 방어 코드는 복잡하고 반복적 -> 대표적 boilerplate code
- 애노테이션 기반으로 데이터 검증을 돕는 JSR-303, JSR-380 표준이 도입됨
- 검증 구현과 비즈니스 로직을 분리하고, 비즈니스 로직에 더 집중 가능하다.
- 코드가 간결해지고 가독성이 향상된다.
- Spring에서는 Validation 의존성 추가해서 사용
- @Validated + 메소드 파라미터 검증
- 메소드 파라미터에 validation annotation을 직접 사용해서 검증하는 방법
- 클래스에 @Validated 붙여서 사용
- 발생한 예외를 ConstraintViolationException으로 던진다. 직접 처리해야하는 예외이다.
- ConfigurationProperties 클래스에도 적용 가능 하다.
- @Valid + Data Object
- 검증하려는 특정 데이터 오브젝트에만 검증 로직을 적용 할 때 사용
- @Validated가 필요하지 않다.
- MethodArgumentNotValidException 예외로 던진다.
- ResponseEntityExceptionHandler 지원을 받을 수 있다.
// APIEventController
import javax.validation.constraints.Positive;
import javax.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.List;
@Validated // 메서드 파라미터에 대한 유효성 검사를 활성화합니다.
@RequiredArgsConstructor // final 필드를 가진 생성자를 생성합니다.
@RequestMapping("/api") // 이 컨트롤러의 기본 URL을 "/api"로 지정합니다.
@RestController // RESTful API 컨트롤러임을 나타냅니다.
public class ApiEventController {
private final EventService eventService; // EventService 의존성 주입
// GET 요청에 대한 핸들러 메서드를 정의합니다.
@GetMapping("/events") // "/api/events" 엔드포인트에 매핑됩니다.
public ApiDataResponse<List<EventResponse>> getEvents(
@Positive Long placeId, // placeId는 양의 숫자여야 합니다.
@Size(min = 2) String eventName, // eventName은 최소 길이가 2여야 합니다.
EventStatus eventStatus, // eventStatus는 옵셔널하게 제공됩니다.
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime eventStartDatetime, // eventStartDatetime은 ISO 날짜와 시간 형식이어야 합니다.
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime eventEndDatetime // eventEndDatetime은 ISO 날짜와 시간 형식이어야 합니다.
) {
// EventService를 사용하여 이벤트를 검색하고, 그 결과를 EventResponse로 매핑하여 반환합니다.
List<EventResponse> response = eventService
.getEvents(placeId, eventName, eventStatus, eventStartDatetime, eventEndDatetime)
.stream().map(EventResponse::from).toList();
// API 응답 데이터를 생성하여 반환합니다.
return ApiDataResponse.of(response);
}