No mundo do desenvolvimento de software, validações são um aspecto essencial para garantir que os dados inseridos pelos usuários estejam corretos. Em Java, você pode criar validações personalizadas para diferentes cenários. Neste post, vamos aprender como criar uma annotation customizada para validar documentos como CPF e CNPJ utilizando o pacote javax.validation
.
O que vamos fazer?
Vamos criar uma annotation chamada @CPFCNPJ
que pode ser aplicada em campos que recebem um CPF ou CNPJ. A annotation vai utilizar um validador customizado, chamado DocumentoValidator
, que será responsável por verificar se o valor inserido é válido de acordo com as regras do CPF ou CNPJ.
Passo 1: Criando a Annotation @CPFCNPJ
Primeiramente, criamos a annotation que será usada para marcar os campos que precisam ser validados. Aqui está o código da annotation:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Constraint(validatedBy = DocumentoValidator.class) // Indica qual será o validador
@Target({ ElementType.FIELD }) // Aplica-se a campos
@Retention(RetentionPolicy.RUNTIME) // Disponível em tempo de execução
public @interface CPFCNPJ {
String message() default "Documento inválido"; // Mensagem padrão de erro
Class<?>[] groups() default {}; // Para agrupar validações
Class<? extends Payload>[] payload() default {}; // Para adicionar dados adicionais ao validador
}
Neste código:
- A annotation
@Constraint
associa a annotation@CPFCNPJ
ao validadorDocumentoValidator
. - A annotation pode ser aplicada a campos com
@Target({ ElementType.FIELD })
. - A mensagem de erro padrão é "Documento inválido", mas pode ser personalizada.
-
groups
epayload
são utilizados em validações mais avançadas, mas não são necessários para este exemplo básico.
Passo 2: Criando o Validador DocumentoValidator
Agora, vamos criar a classe DocumentoValidator
, que será responsável por validar os documentos CPF e CNPJ. Ela implementa a interface ConstraintValidator
, que recebe a annotation e o tipo de dado a ser validado (no nosso caso, uma string que representa o CPF ou CNPJ).
Aqui está o código do DocumentoValidator
:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class DocumentoValidator implements ConstraintValidator<CPFCNPJ, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return false; // Se o campo for nulo ou vazio, é considerado inválido
}
return validarDocumento(value); // Chama o método que valida CPF ou CNPJ
}
private static boolean validarCPF(String cpf) {
if (cpf == null || cpf.length() != 11 || !cpf.matches("[0-9]{11}")) {
return false;
}
if (cpf.matches("(\\d)\\1{10}")) {
return false; // Não permite CPFs com números repetidos
}
int soma = 0;
int peso = 10;
for (int i = 0; i < 9; i++) {
soma += Character.getNumericValue(cpf.charAt(i)) * peso--;
}
int digito1 = 11 - (soma % 11);
if (digito1 == 10 || digito1 == 11) digito1 = 0;
soma = 0;
peso = 11;
for (int i = 0; i < 10; i++) {
soma += Character.getNumericValue(cpf.charAt(i)) * peso--;
}
int digito2 = 11 - (soma % 11);
if (digito2 == 10 || digito2 == 11) digito2 = 0;
return digito1 == Character.getNumericValue(cpf.charAt(9)) && digito2 == Character.getNumericValue(cpf.charAt(10));
}
private static boolean validarCNPJ(String cnpj) {
if (cnpj == null || cnpj.length() != 14 || !cnpj.matches("[0-9]{14}")) {
return false;
}
if (cnpj.matches("(\\d)\\1{13}")) {
return false; // Não permite CNPJs com números repetidos
}
int soma = 0;
int[] peso1 = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
for (int i = 0; i < 12; i++) {
soma += Character.getNumericValue(cnpj.charAt(i)) * peso1[i];
}
int digito1 = 11 - (soma % 11);
if (digito1 == 10 || digito1 == 11) digito1 = 0;
soma = 0;
int[] peso2 = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
for (int i = 0; i < 13; i++) {
soma += Character.getNumericValue(cnpj.charAt(i)) * peso2[i];
}
int digito2 = 11 - (soma % 11);
if (digito2 == 10 || digito2 == 11) digito2 = 0;
return digito1 == Character.getNumericValue(cnpj.charAt(12)) && digito2 == Character.getNumericValue(cnpj.charAt(13));
}
private static boolean validarDocumento(String documento) {
if (documento == null) {
return false;
}
documento = documento.replaceAll("[^0-9]", ""); // Remove caracteres não numéricos
if (documento.length() == 11) {
return validarCPF(documento);
} else if (documento.length() == 14) {
return validarCNPJ(documento);
}
return false; // Se o comprimento não for nem 11 nem 14, retorna inválido
}
}
Passo 3: Utilizando a Annotation
Agora que já criamos a annotation e o validador, podemos aplicá-los em um modelo de dados. Por exemplo, vamos validar um CPF ou CNPJ em um campo de um DTO (Data Transfer Object).
import javax.validation.constraints.NotEmpty;
public class UsuarioDTO {
@CPFCNPJ(message = "CPF ou CNPJ inválido") // Aplica a validação customizada
@NotEmpty(message = "Documento não pode ser vazio")
private String documento;
// Getters e Setters
public String getDocumento() {
return documento;
}
public void setDocumento(String documento) {
this.documento = documento;
}
}
Passo 4: Realizando a Validação
Para realizar a validação, você pode usar o Validator
do Bean Validation. Aqui está um exemplo simples de como validar a classe UsuarioDTO
:
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.ConstraintViolation;
import java.util.Set;
public class Main {
public static void main(String[] args) {
UsuarioDTO usuario = new UsuarioDTO();
usuario.setDocumento("123.456.789-09"); // Insira o CPF ou CNPJ a ser validado
// Cria o validador
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// Valida o objeto
Set<ConstraintViolation<UsuarioDTO>> violations = validator.validate(usuario);
// Verifica se há erros
for (ConstraintViolation<UsuarioDTO> violation : violations) {
System.out.println(violation.getMessage()); // Exibe a mensagem de erro
}
}
}
Conclusão
Neste post, mostramos como criar uma annotation customizada para validar CPF e CNPJ em Java. Utilizamos a especificação Bean Validation (JSR 303) para criar a annotation @CPFCNPJ
, um validador DocumentoValidator
e mostramos como aplicar e utilizar a validação em um campo de um modelo de dados.
Com isso, você pode facilmente validar CPFs e CNPJs em seus projetos Java, mantendo o código limpo e reutilizável.
Top comments (0)