<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andre Barreto</title>
    <description>The latest articles on DEV Community by Andre Barreto (@andreluisbarreto).</description>
    <link>https://dev.to/andreluisbarreto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F68477%2F3e6119be-d3d5-45db-8d03-341af88a0471.png</url>
      <title>DEV Community: Andre Barreto</title>
      <link>https://dev.to/andreluisbarreto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andreluisbarreto"/>
    <language>en</language>
    <item>
      <title>Introdução ao Bean Validation: Deixe o Java Trabalhar!</title>
      <dc:creator>Andre Barreto</dc:creator>
      <pubDate>Mon, 01 Nov 2021 22:15:57 +0000</pubDate>
      <link>https://dev.to/andreluisbarreto/introducao-ao-bean-validation-deixe-o-java-trabalhar-40ai</link>
      <guid>https://dev.to/andreluisbarreto/introducao-ao-bean-validation-deixe-o-java-trabalhar-40ai</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;A validação de dados é uma parte importante e corriqueira de qualquer sistema, seja ela a partir de dados informados por um usuário humano, um androide, uma I.A... &lt;/p&gt;

&lt;p&gt;Porém, também é uma das tarefas mais maçantes que temos que realizar enquanto programadores. Normalmente, no back-end, ela é feita de forma manual na camada de controle ou de serviços, utilizando-se no pior caso If's alinhados e no &lt;em&gt;menos pior&lt;/em&gt; métodos e classes específicas.&lt;/p&gt;

&lt;center&gt;
![Validação manual](https://dev-to-uploads.s3.amazonaws.com/i/w49kmjosmbewr34ox4ed.PNG)
######Típica validação manual
&lt;/center&gt;

&lt;p&gt;Ok! Se você tiver um objeto com 4 ou 5 atributos criar um método para validá-los não é tão ruim, mas no mundo real as coisas não são tão simples, e em muitas ocasiões você pode acabar com objetos repletos de atributos, regras e domínios específicos. E é neste momento de caos que a Bean Validation(JSR-380) vai te ajudar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://beanvalidation.org/2.0-jsr380/" rel="noopener noreferrer"&gt;Bean Validation JSR-380&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como todas as API's do java, ela possui uma especificação, que pode ser consultada no link acima, e uma implementação padrão, no caso, o &lt;a href="https://dev.toHibernate%20Validator"&gt;Hibernate Validator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Na prática
&lt;/h2&gt;

&lt;p&gt;Para ilustrar, vamos considerar como exemplo uma simples aplicação de cadastro de usuários:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38oq9w0dsd6r5vdd508w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38oq9w0dsd6r5vdd508w.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OBS: O código-fonte completo do exemplo está disponível no &lt;a href="https://github.com/alabvix/ubaseapi" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O usuário acessa uma URl para realizar seu cadastro (sign-in), fornecendo os seguintes dados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;userName&lt;/li&gt;
&lt;li&gt;email&lt;/li&gt;
&lt;li&gt;confirmEmail&lt;/li&gt;
&lt;li&gt;password&lt;/li&gt;
&lt;li&gt;confirmPassword&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E as regras de validação para o cadastro são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nenhum dado pode ser null e nem vazio. &lt;/li&gt;
&lt;li&gt;O email precisa ser único.&lt;/li&gt;
&lt;li&gt;O email precisa ser válido.&lt;/li&gt;
&lt;li&gt;O userName precisa ser único.&lt;/li&gt;
&lt;li&gt;O usuário precisa confirmar o email.&lt;/li&gt;
&lt;li&gt;O usuário precisa confirmar o password.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Se o cadastro for bem sucedido, um registro para o usuário é criado e o sistema retorna o código HTTP 201.&lt;/li&gt;
&lt;li&gt;Caso alguma validação não passe, nenhum registro é criado e o sistema retorna o código HTTP 400.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos utilizar o Apache Maven como gerenciador do ciclo de vida e dependências. As dependências para a Bean Validation são as seguintes:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq43a6xs0jg4qds022qbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq43a6xs0jg4qds022qbg.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Para a entrada de dados, vamos utilizar um Dto bem simples:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2r50utgr5srah7s2eny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2r50utgr5srah7s2eny.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Bean Validation funciona através de annotations, e com elas vamos garantir as regras de campos não nulos, vazios e emails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NotNull&lt;/li&gt;
&lt;li&gt;NotEmpty&lt;/li&gt;
&lt;li&gt;NotBlank&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsc3lhvcpkudau9ae0w5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsc3lhvcpkudau9ae0w5z.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que para cada annotation também podemos definir uma mensagem padrão. Essa mensagem será retornada pelo Validator.&lt;/p&gt;

&lt;p&gt;Porém, para que o Dto seja realmente validado, precisamos informar ao Spring, e fazemos isso no controlador usando a anotação &lt;a class="mentioned-user" href="https://dev.to/valid"&gt;@valid&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2wni3p0o4v6if524r9eh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2wni3p0o4v6if524r9eh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os erros de validação podem ser interceptados em tempo de execução e devidamente tratados:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8hxf0p99emwsek0bb5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8hxf0p99emwsek0bb5z.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso já possuímos uma validação básica, contudo, existem situações mais específicas, onde somente as anotações padrão não bastam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizando os validadores
&lt;/h2&gt;

&lt;p&gt;Um dos nossos requisitos é bem específico:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2. O email precisa ser único.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nesse caso, será necessário um validador exclusivo. Para tal, vamos criar uma anotação que vai executar uma classe de validação customizada:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4c647th22qn9c3a9p10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4c647th22qn9c3a9p10.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Na linha 10 definimos o alvo desse validador, no caso, um campo: ElementType.Field.&lt;/li&gt;
&lt;li&gt;Na linha 11 definimos que essa anotação será acessada em Runtime. &lt;/li&gt;
&lt;li&gt;Na linha 12 temos o trecho mais importante, onde definimos a classe concreta que conterá a lógica para a validação de dados: EmailAlreadyExistsValidator.class:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eqo9ws1xkwuhps51abm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eqo9ws1xkwuhps51abm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que na classe de implementação também definimos qual interface será utilizada.&lt;/p&gt;

&lt;p&gt;O método &lt;strong&gt;isValid&lt;/strong&gt; será chamado pela API e é onde devemos implementar nossa lógica:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk10dlo44qtotkv781nua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk10dlo44qtotkv781nua.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após a criação da Inteface e do Método, podemos então anotar no Dto diretamente no campo em que vamos utilizar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frih8sapcn4wd1hz7fg9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frih8sapcn4wd1hz7fg9w.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ordem de validação e validation Groups
&lt;/h2&gt;

&lt;p&gt;Podemos também definir em qual ordem as validações serão executadas, principalmente, quando temos muitas validações a serem realizadas.&lt;/p&gt;

&lt;p&gt;Para tal, devemos implementar &lt;strong&gt;grupos de validação&lt;/strong&gt; e usar a anotação @GroupSequence para definir a ordem: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Forgfyqyhev7a1vbyjhwy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Forgfyqyhev7a1vbyjhwy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, em cada campo devemos definir a qual grupo ele está ligado:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57r6im39ahcetsug3rl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57r6im39ahcetsug3rl8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma, conseguimos garantir que a validação seja feita de forma simples, manutenível e extensível. Verifique o código-fonte para mais exemplos, inclusive a parte de testes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validando através do código
&lt;/h2&gt;

&lt;p&gt;Em algumas situações pode ser necessário um maior controle na execução das validações, como por exemplo, quando necessitamos capturar as mensagens de erro durante um processamento sem interrompê-lo. &lt;/p&gt;

&lt;p&gt;Nesse caso, devemos chamar programaticamente a API. &lt;br&gt;
Considere a seguinte classe:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouqlhvtya4tg26qv6e40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouqlhvtya4tg26qv6e40.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao invés de chamar automaticamente a validão no controlador com o &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/valid"&gt;@valid&lt;/a&gt;&lt;/strong&gt;, vamos criar um método no service e dentro dele chamaremos a validação:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hkpgfxmk0v9maohsxzm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hkpgfxmk0v9maohsxzm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No método &lt;strong&gt;validate&lt;/strong&gt; utilizamos um ValidationFactory para obter o validador e então chamar a validação:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofkpz4zlcaeee3438je6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofkpz4zlcaeee3438je6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para testar a validação:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpymeguonqb2reoawb22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpymeguonqb2reoawb22.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma obtemos mais flexibilidade nas situações onde precisamos de um maior controle. &lt;/p&gt;

&lt;p&gt;E chegamos ao final! Espero que o artigo possa te ajudar no seu dia-a-dia, e caso queira conferir melhor o código, ele está disponível no &lt;strong&gt;&lt;a href="https://github.com/alabvix/ubaseapi" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/strong&gt;. Muito Obrigado! &lt;/p&gt;

</description>
      <category>java</category>
      <category>validation</category>
      <category>portuguese</category>
      <category>spring</category>
    </item>
  </channel>
</rss>
