Spring boot Validation

Vamos lá! como de costume vamos aproveitar o projeto desse post que já está com serviços de inset, update e delete. Agora vamos mostrar como fazer a validação desses dados no insert e update. Primeiramente vamos adicionar as anotações no DTO. Como são os DTOs que trafegam na rede, a validação vai está neles.

  package com.br.davifelipe.springjwt.dto;
 import javax.validation.constraints.NotNull;
  import javax.validation.constraints.Size;
 import lombok.Data;
 @Data
  public class CategoryDTO {
      
      Integer id;
      
      @NotNull
      @Size(min=2, max=30)
      String name;
  }
  

Vamos tentar inserir um registro vazio e ver o que acontece

Imagem

Ok. A validação está funcionando. Mas vamos personalizar o formado desse JSON conforme já fizemos nesse outro post onde criamos um ExceptionHandler para capturar Exceptions do tipo ObjectNotFoundException retornando um objeto StandardError que criamos anteriormente. Para capturar esse outro tipo de Exception precisamos saber qual tipo de exception foi disparada:

Imagem

Nesse caso foi MethodArgumentNotValidException. Esse tipo de excetion é diferente. Nesse caso temos uma lista de erros com os nomes dos campos e o erro de validação de cada campo. Nesse caso precisamos criar outra classe parecida com StandardError. Mas essa outra classe vai ter uma lista de erros vem da exception MethodArgumentNotValidException.

A ideia é capturar essa lista e passar para o nosso objeto. Dessa forma vamos criar uma nova classe chamada ValidationError herdando todos os atributos de StandardError mas com uma novo atributo para armazenar a lista de erros. 

  package com.br.davifelipe.springjwt.resources.exceptions;
 import java.util.ArrayList;
  import java.util.List;
 import lombok.Getter;
 public class ValidationError extends StandardError{
     private static final long serialVersionUID = 1L;
      
      @Getter
      private List<FieldMessage> errors = new ArrayList<FieldMessage>();
      
      public ValidationError(Integer status, String msg, Long timeStamp) {
          super(status, msg, timeStamp);
          // TODO Auto-generated constructor stub
      }
     public void addError(String fieldName, String message) {
          
          this.errors.add(new FieldMessage(fieldName, message));
      }
      
  }
  

Essa lista de erros vai armazerar uma lista de objetos do tipo FieldMessage que devemos criar também

  package com.br.davifelipe.springjwt.resources.exceptions;
 import java.io.Serializable;
 import lombok.AllArgsConstructor;
  import lombok.Data;
  import lombok.NoArgsConstructor;
 @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public class FieldMessage implements Serializable{
     private static final long serialVersionUID = 1L;
      
      private String fieldName;
      private String message;
  }
  

Objetos dessa classe vão armazenar o nome do campo e o erro.

Finalmente vamos acresentar o método em ResourceExceptionHandle para capturar Exceptions do tipo MethodArgumentNotValidException, armazenar a lista de erros e mostrar no corpo da requisição no formato StandardError (Parão de erro que definimos)

  package com.br.davifelipe.springjwt.resources.exceptions;
 import javax.servlet.http.HttpServletRequest;
 import org.springframework.http.HttpStatus;
  import org.springframework.http.ResponseEntity;
  import org.springframework.validation.FieldError;
  import org.springframework.web.bind.MethodArgumentNotValidException;
  import org.springframework.web.bind.annotation.ControllerAdvice;
  import org.springframework.web.bind.annotation.ExceptionHandler;
 import com.br.davifelipe.springjwt.services.exceptions.ObjectNotFoundException;
 @ControllerAdvice
  public class ResourceExceptionHandle {
      
      @ExceptionHandler(ObjectNotFoundException.class)
      public ResponseEntity<StandardError> objectNotFound(ObjectNotFoundException e,
                                                          HttpServletRequest request){
          StandardError err = new StandardError(HttpStatus.NOT_FOUND.value(), e.getMessage(), System.currentTimeMillis());
          
          return ResponseEntity.status(HttpStatus.NOT_FOUND).body(err);
      }
      
      @ExceptionHandler(MethodArgumentNotValidException.class)
      public ResponseEntity<StandardError> validation(MethodArgumentNotValidException e,
                                                          HttpServletRequest request){
          ValidationError err = new ValidationError(HttpStatus.BAD_REQUEST.value(), "Validation Error", System.currentTimeMillis());
          
          for(FieldError field : e.getBindingResult().getFieldErrors()) {
              err.addError(field.getField(), field.getDefaultMessage());
          }
          
          return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(err);
      }
      
  }
  

Agora todas as exceptions do tipo MethodArgumentNotValidException serão capturadas pelo nosso handle e serão exibidas no formato que definimos

Imagem

https://github.com/davifelipems/spring-backend-template/tree/validation

Comentários

 

Quem Sou

Graduado em ADS (Análise e desenvolvimento de sistemas).

Não sou "devoto" de nenhuma linguagem de programação. Procuro aproveitar o melhor de cada uma de acordo com a necessidade do projeto. Prezo por uma arquitetura bem feita, código limpo, puro e simples! 

anuncio atendente