Catálogo de Anotações de Validação
A especificação Bean Validation fornece um conjunto robusto de anotações para garantir a integridade dos dados de entrada sem a necessidade de escrever blocos condicionais complexos. Abaixo estão as diretivas mais empregadas no ecossistema Java:
| Anotação | Tipos Suportados | Comportamento Esperado |
|---|---|---|
@Null |
Qualquer tipo | O campo deve ser estritamente nulo. |
@NotNull |
Qualquer tipo | Rejeita valores nulos, mas permite strings vazias. |
@NotBlank |
CharSequence | Exige que a string não seja nula e possua pelo menos um caractere que não seja espaço em branco. |
@NotEmpty |
CharSequence, Collection, Map, Array | O tamanho do elemento deve ser maior que zero. Strings contando apenas espaços são consideradas válidas. |
@Size |
CharSequence, Collection, Map, Array | Restringe a quantidade de elementos ou caracteres a um intervalo definido por min e max. |
@Range |
Números, CharSequence | O valor numérico (ou texto numérico) deve estar compreendido entre um limite mínimo e máximo. |
@Length |
CharSequence | Valida especificamente o número de caracteres de uma string. |
@Pattern |
CharSequence | O texto deve corresponder exatamente à expressão regular fornecida. |
@Min / @Max |
Tipos numéricos inteiros | Define, respectivamente, o valor mínimo e máximo absoluto permitido. |
@DecimalMin / @DecimalMax |
BigDecimal, BigInteger, CharSequence, Tipos numéricos | Similar ao Min/Max, porém projetado para suportar precisão decimal e validação via string. |
@AssertTrue |
boolean, Boolean | O valor avaliado deve resultar em verdadeiro. |
@AssertFalse |
boolean, Boolean | O valor avaliado deve resultar em falso. |
@Past |
API de Data/Hora (java.time, Date) | A data informada deve ser estritamente anterior ao instante atual. |
@Future |
API de Data/Hora (java.time, Date) | A data informada deve ser estritamente posterior ao instante atual. |
Comparativo Técnico: @Validated versus @Valid
Ambas as anotações disparam o mecanismo de verificação de constraints, mas operam em camadas distintas do framework e possuem escopos de atuação diferentes.
Origem e Provedor
@Validated: É uma variação proprietária introduzida pelo Spring Framework. Sua principal vantagem sobre a anotação padrão é o suporte nativo a grupos de validação (Validation Groups).@Valid: Pertence à especificação oficial Java (JSR-303 / JSR-380), residindo nos pacotesjavax.validationoujakarta.validation.
Escopos de Aplicação
A anotação @Validated pode ser aplicada em nível de classe (Type), método e parâmetros de método. Por outro lado, @Valid possui um alcance mais amplo, suportando métodos, campos, construtores, parâmetros e, a partir do Java 8, o contexto TYPE_USE.
O recurso TYPE_USE (Type Annotations) permite que anotações sejam inseridas em qualquer local do código onde um tipo de dados seja referenciado. Isso inclui operações de instanciação, conversão (cast), implementação de interfaces genéricas e declaração de exceções:
// Validação acionada durante a instanciação
Transaction transaction = new @Valid Transaction();
// Validação aplicada no processo de type casting
transaction = (@Valid Transaction) rawPayload;
// Restrição em tipos genéricos de uma interface
public class MessageBroker<T> implements Publisher<@Valid T> {
// lógica de publicação
}
// Anotação na assinatura de exceções de método
public void executePayment() throws @Valid InsufficientFundsException {
// processamento financeiro
}
Validação em Cascata de Objetos Aninhados
Quando um DTO possui propriedades que são objetos complexos ou coleções de outros objetos, a validação não ocorre recursivamente por padrão. Para forçar o motor de validação a inspecionar as propriedades internas de uma classe referenciada, utiliza-se a anotação @Valid diretamente sobre o atributo.
No cenário abaixo, a classe Order possui uma lista de OrderItem. Sem a anotação de cascata, o framework apenas verificaria se a lista em si atende à regra de tamanho. Ao adicionar @Valid, as constraints definidas dentro de OrderItem (como a obrigatoriedade do SKU e o preço mínimo) também são avaliadas.
public class Order {
@Valid
@Size(min = 1, message = "A requisição deve conter pelo menos um item no pedido.")
private List<OrderItem> items;
// getters e setters
}
public class OrderItem {
@NotBlank(message = "O código do produto não pode estar em branco.")
@Length(min = 4, max = 20, message = "O SKU deve ter entre 4 e 20 caracteres.")
private String productSku;
@NotNull
@DecimalMin(value = "0.01", message = "O preço unitário deve ser superior a zero.")
private BigDecimal unitPrice;
// getters e setters
}