@Validated는 스프링 프레임워크에서 제공하는 어노테이션으로, 그룹 검증 기능과 메소드 레벨의 검증을 가능하게 합니다. 이는 @Valid의 기능을 확장한 스프링 특화 어노테이션입니다.
기본적인 사용 방법은 다음과 같습니다:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Validated
public class UserController {
@PostMapping("/users")
public User createUser(@Validated(CreateUser.class) @RequestBody User user) {
return userService.createUser(user);
}
@PostMapping("/users/update")
public User updateUser(@Validated(UpdateUser.class) @RequestBody User user) {
return userService.updateUser(user);
}
}
public class User {
@NotNull(groups = {CreateUser.class, UpdateUser.class})
private String username;
@NotNull(groups = CreateUser.class)
@Email(groups = {CreateUser.class, UpdateUser.class})
private String email;
// getters and setters
}
public interface CreateUser {}
public interface UpdateUser {}
@Valid 포함: @Validated는 @Valid의 모든 기능을 포함하며, 추가 기능을 제공합니다.@Service
@Validated
public class UserService {
public User createUser(@NotNull @Size(min = 2, max = 30) String username,
@Email String email) {
// 메소드 구현
}
}
@Service
@Validated
public class ProductService {
@NotNull
@Size(min = 1)
public List<Product> getProducts() {
// 메소드 구현
}
}
public class Order {
@Valid
@NotNull(groups = {CreateOrder.class, UpdateOrder.class})
private List<@Validated(CreateOrderItem.class) OrderItem> items;
// other fields, getters and setters
}
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = OrderValidator.class)
public @interface ValidOrder {
String message() default "Invalid order";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Service
@Validated
public class OrderService {
public void processOrder(@ValidOrder Order order) {
// 메소드 구현
}
}
@Validated로 인한 검증 실패 시 ConstraintViolationException이 발생합니다. 이를 처리하는 방법:
@RestControllerAdvice
public class ValidationExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Map<String, List<String>>> handleValidationErrors(ConstraintViolationException ex) {
List<String> errors = ex.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toList());
return new ResponseEntity<>(getErrorsMap(errors), new HttpHeaders(), HttpStatus.BAD_REQUEST);
}
private Map<String, List<String>> getErrorsMap(List<String> errors) {
Map<String, List<String>> errorResponse = new HashMap<>();
errorResponse.put("errors", errors);
return errorResponse;
}
}
@Validated가 적용된 서비스나 컨트롤러를 테스트할 때:
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@Test
void whenInvalidUsername_thenThrowsException() {
assertThrows(ConstraintViolationException.class, () -> {
userService.createUser("a", "user@example.com");
});
}
}
@Validated는 스프링 AOP 프록시를 통해 동작하므로, 같은 클래스 내의 메소드 호출에는 적용되지 않습니다.@Validated는 스프링에서 제공하는 강력한 검증 도구입니다. @Valid의 기능을 확장하여 그룹 검증과 메소드 레벨 검증을 가능하게 함으로써, 더욱 세밀하고 상황에 맞는 데이터 검증을 수행할 수 있게 해줍니다. 특히 복잡한 비즈니스 규칙이나 다양한 검증 시나리오가 필요한 엔터프라이즈 애플리케이션에서 유용하게 사용될 수 있습니다. 다만, 과도한 사용은 애플리케이션의 복잡성을 증가시킬 수 있으므로, 적절한 균형을 유지하는 것이 중요합니다.
@Valid
@ControllerAdvice
@RestController
@Service
@ExceptionHandler