🛡 Spring Tips: Service Layer Validation



Валидация данных – ключевой аспект любого приложения. В Spring она часто используется в параметрах методов @RestController, например:





@RestController

@RequestMapping("/api/products")

public class ProductController {



@GetMapping("/search")

public ResponseEntity<List<Product>> searchProducts(@RequestParam @NotNull @Size(min = 3, max = 50) String name,

@RequestParam @NotNull @Min(0) @Max(10000) Double price) {

// Логика поиска продуктов

List<Product> products = productService.search(name, price);

return new ResponseEntity<>(products, HttpStatus.OK);

}

}





Валидация в сервисном слое



Валидация помогает гарантировать, что данные, поступающие в приложение, соответствуют требованиям. Для валидации в сервисном слое нужно добавить аннотацию @Validated над сервисом:





@Service

@Validated

public class EmailService {

public void send(@Email String email,

@Length(max = 10) String subject,

@NotBlank String body) {

// бизнес-логика

}

}





Теперь метод send вызовет ошибку, если данные не проходят валидацию:





emailService.send(

"i am not email",

"I am too loooooooooong",

""

);







jakarta.validation.ConstraintViolationException: send.body: must not be blank, send.email: must be a well-formed email address, send.subject: length must be between 0 and 10

...





Валидация DTO в методах сервиса



Чтобы не дублировать поля в разных методах, разработчики часто используют DTO. Аннотации валидации применимы и здесь:





public record EmailRequest(

@Email String email,

@Length(max = 10) String subject,

@NotBlank String body

) {

}





Но в этом случае помимо @Validated над классом, нужно также не забыть добавить @Valid перед типом параметра в методе:





@Service

@Validated

public class EmailService {

public void sendBatch(

@Valid List<EmailRequest> requests

) {

// do work

}

}





Следующий код вызовет ошибку:





emailService.sendBatch(

List.of(

new EmailRequest("not email", "test", "Hello"),

new EmailRequest("[email protected]", "I am too loooooooooong", "")

)

);







jakarta.validation.ConstraintViolationException: sendBatch.requests[1].subject: length must be between 0 and 10, sendBatch.requests[1].body: must not be blank, sendBatch.requests[0].email: must be a well-formed email address





Валидация элементов коллекций



Кстати, точно также можно валидировать и элементы коллекций, а также ключи и значения в Map:





@Service

@Validated

public class EmailService {

public void search(

Map<@NotBlank String, @NotBlank String> searchParams

) {

// do work

}

}





Следующий код вызовет ошибку:





searchService.search(Map.of("", ""));







jakarta.validation.ConstraintViolationException: search.searchParams<K>[].<map key>: must not be blank, search.searchParams[].<map value>: must not be blank





#SpringBoot #SpringTips #Validation