2
respostas

[Dúvida] Validar campo CPF_CNPJ

Boa tarde, estou fazendo um projeto para poder praticar Java e Spring boot e, acredito que não seria possível usar os annotations @CPF e @CNPJ simultaneamente na mesma variavel (a minha variável recebe os dois valores CNPJ e CPJ), e queria validar os valores que serão recebidos antes de incluir no banco de dados. Uma forma que encontrei de fazer a validação foi utilizar a biblioteca Caelum Stella e, fazer a validação dentro do método de salvar, gostara de compartilhar e saber se indicariam uma forma melhor de fazer essa validação.

public Parceiro(DadosCadastroParceiro dados) throws ErroDedadosException {

    if (dados.tipoParceiro().contains("Fisica")){

        CPFValidator cpfValidator = new CPFValidator();
        List<ValidationMessage> erros = cpfValidator.invalidMessagesFor(dados.cpf_cnpj());
        if (erros.size() > 0){
            throw new ErroDedadosException("CPF Inválido, por favor informar CPF Válido.");
        }else {
            this.cpf_cnpj = dados.cpf_cnpj();
        }
    }
    else if  (dados.tipoParceiro().contains("Juridica")){
        CNPJValidator cnpjValidator = new CNPJValidator();
        List<ValidationMessage> errosCNPJ = cnpjValidator.invalidMessagesFor(dados.cpf_cnpj());

        if(errosCNPJ.size() > 0){
            throw new ErroDedadosException("CNPJ Inválido, por favor informar CNPJ Válido.");
        }else {
            this.cpf_cnpj = dados.cpf_cnpj();
        }
    }
    this.email = dados.email();
    this.nome = dados.nome();
    this.telefone = dados.telefone();
    this.tipoParceiro = dados.tipoParceiro();
}
2 respostas

Você pode criar uma anotação personalizada que verifica se o valor é um CPF ou CNPJ. Isso elimina a lógica de validação do construtor, mantendo o código mais organizado:

Criação da anotação customizada:

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = CPFouCNPJValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CPFouCNPJ {
    String message() default "CPF ou CNPJ inválido!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Implementação do validador:

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import br.com.caelum.stella.validation.CPFValidator;
import br.com.caelum.stella.validation.CNPJValidator;

public class CPFouCNPJValidator implements ConstraintValidator<CPFouCNPJ, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty()) return false;

        CPFValidator cpfValidator = new CPFValidator();
        CNPJValidator cnpjValidator = new CNPJValidator();

        return cpfValidator.isEligible(value) || cnpjValidator.isEligible(value);
    }
}

Uso no DTO ou na Entidade:

public class DadosCadastroParceiro {
    @CPFouCNPJ
    private String cpf_cnpj;

    // outros campos e métodos...
}

Vantagens dessa abordagem:

  • Validação centralizada e reutilizável.
  • Construtor mais limpo.
  • Integração direta com o Bean Validation, permitindo validação automática ao salvar ou atualizar registros.

Espero que essa solução atenda à sua necessidade.

obrigado, vou tentar implementar aqui