{"componentChunkName":"component---src-templates-blog-post-js","path":"/spring-validacao/","result":{"data":{"markdownRemark":{"html":"<p>Erros ocorrem e sempre irão ocorrer, seja por mal requisito de negócio, seja por mal desenvolvimento ou qualquer outra razão. O fato é que erros acontecem e precisamos saber lidar com eles.</p>\n<p>Mas como vamos apresentar o erro para o usuário ou cliente que chamam as nossas APIs?</p>\n<p>O Spring já fornece todo um mecanismo para <a href=\"https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">tratativa de erros</a> que é muito válido e auxilia, e muito, o desenvolvimento mas aqui eu irei apresentar uma outra forma de realizar essa tratativa através de uma <em>lib</em> que descobri recentemente que facilita ainda mais o trabalho e padronização de erros e mensagens na resposta.</p>\n<h2 id=\"Projeto\" style=\"position:relative;\">Projeto<a href=\"#Projeto\" aria-label=\"Projeto permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>Seguindo com os conteúdos dos artigos anteriores vamos reaproveitar o projeto que já foi usado pra <a href=\"https://programadev.com.br/spring-security-jwt/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Criar um endpoint com Spring Security e token JWT</a> e vamos adicionar nele a validação.</p>\n<p>Este projeto também está sendo usado nos artigos sobre o Kafka aqui do blog e nessa aplicação temos como premissa que seja enviado os dados de um contribuinte como nome, documento e email.</p>\n<p>No nosso projeto hoje não há validação alguma se os dados enviados estão corretos, para esse exemplo queremos que o número do documento (CPF), seja um número válido e caso não seja deve retornar uma mensagem indicando isso.</p>\n<p>Para isso iremos usar uma <em>lib</em> muito interessante que ajuda muito no desenvolvimento com <strong>Spring Boot</strong>, a <a href=\"https://github.com/alimate/errors-spring-boot-starter\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Errors Spring Boot Starter</a> é um projeto que visa facilitar ainda mais a manipulação de erros e validação de dados de entrada.</p>\n<h2 id=\"Adicionado-ao-Maven\" style=\"position:relative;\">Adicionado ao Maven<a href=\"#Adicionado-ao-Maven\" aria-label=\"Adicionado ao Maven permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>O projeto <a href=\"https://github.com/guilhermegarcia86/kafka-series/tree/main/register\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">register</a> é um projeto <strong>Java</strong> que utiliza o <strong>Maven</strong> então basta adicionar a dependência no <code class=\"language-text\">pom.xml</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>dependency</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>groupId</span><span class=\"token punctuation\">></span></span>me.alidg<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>groupId</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>artifactId</span><span class=\"token punctuation\">></span></span>errors-spring-boot-starter<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>artifactId</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>version</span><span class=\"token punctuation\">></span></span>1.4.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>version</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>dependency</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>E para auxiliar nas validações também incluir a dependência do <code class=\"language-text\">spring-boot-starter-validation</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>dependency</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>groupId</span><span class=\"token punctuation\">></span></span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>groupId</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>artifactId</span><span class=\"token punctuation\">></span></span>spring-boot-starter-validation<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>artifactId</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>dependency</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<h2 id=\"Criando-annotation-para-validacao\" style=\"position:relative;\">Criando annotation para validação<a href=\"#Criando-annotation-para-validacao\" aria-label=\"Criando annotation para validacao permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>O nosso objeto de entrada no <strong>POST</strong> contém um campo <strong>documento</strong> que será onde usuário irá enviar o CPF:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"User\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"document\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"XXX.XXX.XXX-XX\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"email\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"email@fake.com\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>E a ideia seria que no momento do <strong>POST</strong> fosse realizada a validação e caso não seja um <strong>CPF</strong> válido retorna um erro informando isso.</p>\n<p>Para isso será criado uma <strong>Annotation</strong> <code class=\"language-text\">@Cpf</code> que nos auxiliará:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Documented</span>\n<span class=\"token annotation punctuation\">@Constraint</span><span class=\"token punctuation\">(</span>validatedBy <span class=\"token operator\">=</span> <span class=\"token class-name\">CpfValidator</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token annotation punctuation\">@Target</span><span class=\"token punctuation\">(</span> <span class=\"token punctuation\">{</span> <span class=\"token class-name\">ElementType</span><span class=\"token punctuation\">.</span>METHOD<span class=\"token punctuation\">,</span> <span class=\"token class-name\">ElementType</span><span class=\"token punctuation\">.</span>FIELD <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token annotation punctuation\">@Retention</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">RetentionPolicy</span><span class=\"token punctuation\">.</span>RUNTIME<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">public</span> <span class=\"token annotation punctuation\">@interface</span> <span class=\"token class-name\">Cpf</span> <span class=\"token punctuation\">{</span>\n\t\n    <span class=\"token class-name\">String</span> <span class=\"token function\">message</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">default</span> <span class=\"token string\">\"Documento Inválido\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">Class</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token operator\">?</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token function\">groups</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">Class</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token operator\">?</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Payload</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token function\">payload</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Na <strong>annotation</strong> <code class=\"language-text\">@Cpf</code> é definida a mensagem que será devolvida para o usuário e também adicionamos <code class=\"language-text\">@Constraint(validatedBy = CpfValidator.class)</code> que é classe que contém a lógica para executar a validação.</p>\n<p>É necessário criar a classe <strong>CpfValidator</strong> que contém a regra de validação:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">CpfValidator</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">ConstraintValidator</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Cpf</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>\n\t\n\t<span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> PESO_CPF <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token number\">11</span><span class=\"token punctuation\">,</span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span> <span class=\"token number\">9</span><span class=\"token punctuation\">,</span> <span class=\"token number\">8</span><span class=\"token punctuation\">,</span> <span class=\"token number\">7</span><span class=\"token punctuation\">,</span> <span class=\"token number\">6</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n\t<span class=\"token annotation punctuation\">@Override</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token keyword\">boolean</span> <span class=\"token function\">isValid</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> cpf<span class=\"token punctuation\">,</span> <span class=\"token class-name\">ConstraintValidatorContext</span> context<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\n\t\t<span class=\"token class-name\">String</span> cpfSomenteDigitos <span class=\"token operator\">=</span> cpf<span class=\"token punctuation\">.</span><span class=\"token function\">replaceAll</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\\\\D\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t\n\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>cpfSomenteDigitos <span class=\"token operator\">==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> <span class=\"token punctuation\">(</span>cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">11</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"00000000000\"</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"11111111111\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"22222222222\"</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"33333333333\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"44444444444\"</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"55555555555\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"66666666666\"</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"77777777777\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"88888888888\"</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token operator\">||</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"99999999999\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t\t\n\t\t<span class=\"token class-name\">Integer</span> digito1 <span class=\"token operator\">=</span> <span class=\"token function\">calcularDigito</span><span class=\"token punctuation\">(</span>cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">substring</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> PESO_CPF<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token class-name\">Integer</span> digito2 <span class=\"token operator\">=</span> <span class=\"token function\">calcularDigito</span><span class=\"token punctuation\">(</span>cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">substring</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> digito1<span class=\"token punctuation\">,</span> PESO_CPF<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\t\t<span class=\"token keyword\">return</span> cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">equals</span><span class=\"token punctuation\">(</span>cpfSomenteDigitos<span class=\"token punctuation\">.</span><span class=\"token function\">substring</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> digito1<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> digito2<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\t\n\t<span class=\"token keyword\">private</span> <span class=\"token keyword\">int</span> <span class=\"token function\">calcularDigito</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> str<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> peso<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">int</span> soma <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> indice <span class=\"token operator\">=</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> digito<span class=\"token punctuation\">;</span> indice <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> indice<span class=\"token operator\">--</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\tdigito <span class=\"token operator\">=</span> <span class=\"token class-name\">Integer</span><span class=\"token punctuation\">.</span><span class=\"token function\">parseInt</span><span class=\"token punctuation\">(</span>str<span class=\"token punctuation\">.</span><span class=\"token function\">substring</span><span class=\"token punctuation\">(</span>indice<span class=\"token punctuation\">,</span> indice <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t\tsoma <span class=\"token operator\">+=</span> digito <span class=\"token operator\">*</span> peso<span class=\"token punctuation\">[</span>peso<span class=\"token punctuation\">.</span>length <span class=\"token operator\">-</span> str<span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> indice<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t\tsoma <span class=\"token operator\">=</span> <span class=\"token number\">11</span> <span class=\"token operator\">-</span> soma <span class=\"token operator\">%</span> <span class=\"token number\">11</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token keyword\">return</span> soma <span class=\"token operator\">></span> <span class=\"token number\">9</span> <span class=\"token operator\">?</span> <span class=\"token number\">0</span> <span class=\"token operator\">:</span> soma<span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>A primeira coisa a se notar nessa classe é que ela implementa a interface do <em>javax.validation</em> <strong>ConstraintValidator&#x3C;A extends Annotation, T></strong> que recebe uma <strong>Annotation</strong> como parâmetro.</p>\n<p>E aqui executamos o algoritmo para validarmos se um CPF é válido ou não.</p>\n<p>Para que a validação tenha efeito é necessário adicionar no <strong>Controller</strong> que recebe o nosso objeto a anotação <code class=\"language-text\">@Valid</code> para que surja efeito.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token class-name\">ResponseEntity</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">TaxpayerDTO</span><span class=\"token punctuation\">></span></span> <span class=\"token function\">postTaxpayer</span><span class=\"token punctuation\">(</span><span class=\"token annotation punctuation\">@Valid</span> <span class=\"token annotation punctuation\">@RequestBody</span> <span class=\"token class-name\">TaxpayerDTO</span> taxpayer<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Com isso nós podemos adicionar essa <strong>Annotation</strong> ao atributo <code class=\"language-text\">document</code> no DTO <strong>TaxpayerDTO</strong>.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Cpf</span>\n<span class=\"token keyword\">private</span> <span class=\"token class-name\">String</span> document<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Se tentarmos agora fazer um <strong>POST</strong> com um número que não seja um CPF válido será lançado o erro com status 400.</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"errors\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token property\">\"code\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Documento invalido\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token null keyword\">null</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Já retorna uma mensagem de erro mais padronizada porém um tanto quanto estranha já que a <em>message</em> está com valor <code class=\"language-text\">null</code> e no campo <em>code</em> está com a mensagem que definimos na <strong>Annotation</strong> CPF.</p>\n<p>Isso ocorre pois a nossa dependência de validação usa o mecanismo do <strong>Spring MessageSource</strong> para buscar as mensagens que serão exibidas, então precisamos criar o nosso arquivo <code class=\"language-text\">messages.properties</code> na pasta <strong>Resources</strong> do projeto e lá adicionamos as mensagens.</p>\n<div class=\"gatsby-highlight\" data-language=\"properties\"><pre class=\"language-properties\"><code class=\"language-properties\"><span class=\"token attr-name\">invalid.document</span><span class=\"token punctuation\">=</span><span class=\"token attr-value\">Documento invalido</span></code></pre></div>\n<p>E alteramos também na annotation com chave da mensagem.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token class-name\">String</span> <span class=\"token function\">message</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">default</span> <span class=\"token string\">\"invalid.document\"</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Fazendo isso a tentando novamente com um CPF que é inválido o retorno será esse:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"errors\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token property\">\"code\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"invalid.document\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Documento invalido\"</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"Criando-um-Exception-customizada\" style=\"position:relative;\">Criando um Exception customizada<a href=\"#Criando-um-Exception-customizada\" aria-label=\"Criando um Exception customizada permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>Outra <em>feature</em> interessante dessa biblioteca é a capacidade de poder fazer a tratativa dos erros nas <strong>Exceptions</strong> que criamos na aplicação.</p>\n<p>Vamos criar uma <strong>Exception</strong> para simular um cenário e poder ficar mais claro, imaginemos que há uma regra na nossa aplicação onde não seja aceito pessoas com o nome <em>Guilherme</em> e vamos verificar isso na nossa classe que executa as regras de negócio:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\">\t<span class=\"token annotation punctuation\">@Override</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">CommonDTO</span> taxpayerDTO<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\n\n\t\t<span class=\"token class-name\">TaxPayer</span> taxPayer <span class=\"token operator\">=</span> <span class=\"token class-name\">TaxPayer</span><span class=\"token punctuation\">.</span><span class=\"token function\">newBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">TaxpayerDTO</span><span class=\"token punctuation\">)</span> taxpayerDTO<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\t\t\t\t<span class=\"token punctuation\">.</span><span class=\"token function\">setDocument</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">TaxpayerDTO</span><span class=\"token punctuation\">)</span> taxpayerDTO<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getDocument</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setSituation</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">setEmail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">TaxpayerDTO</span><span class=\"token punctuation\">)</span> taxpayerDTO<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getEmail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t\n\t\t\n        <span class=\"token comment\">// Aqui está o lançamento da Exception</span>\n\t\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>taxPayer<span class=\"token punctuation\">.</span><span class=\"token function\">getName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Guilherme\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\t<span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">BadTaxpayerUser</span><span class=\"token punctuation\">(</span>taxPayer<span class=\"token punctuation\">.</span><span class=\"token function\">getName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t\t\n\t\t\n\t\tproducer<span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">createProducerRecord</span><span class=\"token punctuation\">(</span>taxPayer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>rm<span class=\"token punctuation\">,</span> ex<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n\t\t\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>ex <span class=\"token operator\">==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t\t\tlog<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Data sent with success!!!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t\t<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n\t\t\t\tlog<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Fail to send message\"</span><span class=\"token punctuation\">,</span> ex<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t\t\t<span class=\"token punctuation\">}</span>\n\t\t<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\t\tproducer<span class=\"token punctuation\">.</span><span class=\"token function\">flush</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n\t<span class=\"token punctuation\">}</span></code></pre></div>\n<p>No trecho de código acima temos uma <strong>Exception</strong> que recebe o nome do <em>taxpayer</em>, e será nessa classe de <strong>Exception</strong> que será feita a manipulação do erro para o retorno da <strong>API</strong>:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Getter</span>\n<span class=\"token annotation punctuation\">@ExceptionMapping</span><span class=\"token punctuation\">(</span>statusCode <span class=\"token operator\">=</span> <span class=\"token class-name\">HttpStatus</span><span class=\"token punctuation\">.</span>I_AM_A_TEAPOT<span class=\"token punctuation\">,</span> errorCode <span class=\"token operator\">=</span> <span class=\"token string\">\"bad.user.message\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">BadTaxpayerUser</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">RuntimeException</span> <span class=\"token punctuation\">{</span>\n\t\n    <span class=\"token annotation punctuation\">@ExposeAsArg</span><span class=\"token punctuation\">(</span>value <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> name <span class=\"token operator\">=</span> <span class=\"token string\">\"user\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> key<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">BadTaxpayerUser</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> key<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>key <span class=\"token operator\">=</span> key<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Na <strong>BadTaxpayerUser</strong> bastou adicionarmos uma anotação <code class=\"language-text\">@ExceptionMapping</code> e nela passamos no campo <code class=\"language-text\">statusCode</code> o código HTTP que deve ser retornado e no campo <code class=\"language-text\">errorCode</code> é passado a chave da mensagem, que está em <code class=\"language-text\">resources</code>, que deve ser exibida.</p>\n<p>Antes de vermos a anotação <code class=\"language-text\">@ExposeAsArg</code> iremos adicionar ao arquivo <code class=\"language-text\">message.properties</code> a mensagem que deve ser exibida e vamos customizá-la dessa forma:</p>\n<div class=\"gatsby-highlight\" data-language=\"properties\"><pre class=\"language-properties\"><code class=\"language-properties\"><span class=\"token attr-name\">bad.user.message</span><span class=\"token punctuation\">=</span><span class=\"token attr-value\">O user {user} nao pode!!!</span></code></pre></div>\n<p>Com isso quando adicionarmos a anotação <code class=\"language-text\">@ExposeAsArg</code> no atributo <em>key</em> da <strong>Exception</strong> temos que informar que o primeiro argumento que está entre chaves, <code class=\"language-text\">{user}</code>, deve ser interpolado pelo valor a ser recebido na exceção.</p>\n<p>Agora fazendo o teste e enviando um POST com essas informações, que foram geradas pelo <a href=\"https://www.4devs.com.br/gerador_de_pessoas\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Gerador de pessoas da 4Devs</a>:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Guilherme Paulo Carlos Eduardo Dias\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"document\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"893.475.166-51\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"email\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"guilhermepaulocarloseduardodias-89@3dmaker.com.br\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Teremos como retorno o erro com status <strong>418 I’m a teapot</strong> com o corpo da mensagem:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"errors\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token property\">\"code\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"bad.user.message\"</span><span class=\"token punctuation\">,</span>\n            <span class=\"token property\">\"message\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"O user Guilherme Paulo Carlos Eduardo Dias nao pode!!!\"</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"Conclusao\" style=\"position:relative;\">Conclusão<a href=\"#Conclusao\" aria-label=\"Conclusao permalink\" class=\"anchor after\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a></h2>\n<p>Bom espero nesse artigo ter apresentando um pouco mais sobre a biblioteca <a href=\"https://github.com/alimate/errors-spring-boot-starter\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Errors Spring Boot Starter</a> e suas facilidades. Lembrando que essa é apenas uma outra maneira para lidar com validações. </p>\n<p>O código desse projeto pode ser encontrado no <a href=\"https://github.com/guilhermegarcia86/kafka-series/tree/spring-validation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub</a></p>","fields":{"slug":"/spring-validacao/"},"frontmatter":{"date":"26 de janeiro de 2021","description":"Aprendendo como criar validações customizadas de forma produtiva para sua API","title":"Validando requisições com Spring Boot","tags":["Spring Boot","Validation","Java"],"author":"Guilherme Alves","image":{"id":"f35c4a96-7443-5f7d-83cf-92062165e30c","publicURL":"/static/c54e92f76d845f2963fe6b021614370c/spring-erro.png","childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABx0lEQVQoz41T3StDYRw++QsUya2Sj6SUG00+L6QoRShXyw0jXPiWSJILtRKJ4saF8r1lbT63WBOy2tY2ojSaKB/baLOvcx7be3aObYfy1tPvnPf5/Z7z/N73dyiEFsMwBOwzjSAd4PGzH4nBAGi/n0VAyFMxySGx3xbP00I+ei+cR3HJdETsxf2I3ZtlAs3dOrwBD8vTQRKf9nZgGR8gsMvXYkSJYHzL06ed6FKUY/K4GS2yAsit87yDj9sryFIScCjKgqYsD1uJFN4vzyJHwX6QOKQZ9kVrk2FM3YRtyxwU10tYNUkxfFCHe8c14XUNFdDVV8DQ0wp9hxjn4lqcVBUKW+YEFy4GIdW1Y/FyBN2qSmyaZ9G/Ww21bQPwAjvpiTD0SqCtKYG2ugjGvjYoM5PhsT/wrVPR52dzXBGhFeMUcTd/MYDRo0Z8eT8Jb50cxpEoG+axPlgnhqApzYNpsINvmXcY7XLTPAOJvJC0LpGLoH9UswUhBD1uqItzocxIgionFfv5afC9vcRcDCWYs5Db58972F23ePM88xxX4Hc54bKY4LQY4Xt//fuWo2P8DP5nDrk8SvinMORMw2AIhB2ERTjE138DY6wUY1LzT6MAAAAASUVORK5CYII=","aspectRatio":1.7777777777777777,"src":"/static/c54e92f76d845f2963fe6b021614370c/0823f/spring-erro.png","srcSet":"/static/c54e92f76d845f2963fe6b021614370c/c67b7/spring-erro.png 320w,\n/static/c54e92f76d845f2963fe6b021614370c/d3930/spring-erro.png 640w,\n/static/c54e92f76d845f2963fe6b021614370c/0823f/spring-erro.png 1280w,\n/static/c54e92f76d845f2963fe6b021614370c/c730b/spring-erro.png 1920w,\n/static/c54e92f76d845f2963fe6b021614370c/55bfe/spring-erro.png 2240w","sizes":"(max-width: 1280px) 100vw, 1280px"}}}},"timeToRead":7}},"pageContext":{"slug":"/spring-validacao/","previous":{"fields":{"slug":"/kafka-consumer/"},"frontmatter":{"title":"Consumindo mensagens do Kafka sem dor de cabeça","date":"18 jan, 2021"}},"next":{"fields":{"slug":"/kafka-streams/"},"frontmatter":{"title":"Kafka Streams com Java","date":"02 fev, 2021"}}}},"staticQueryHashes":["63159454"]}