DEV Community

Cover image for Um Projeto Spring Boot - P5.3
Flávia Correia for Devs Jequié

Posted on

Um Projeto Spring Boot - P5.3

Fala pessoal!

Mais um tutorial sobre Rest API em Java com Spring Boot chegando. E hoje vou falar um pouco sobre validações e tratamento de exceções.


Adicionando validação nos campos

Algo que não queremos são erros de exceção gerados no banco de dados por causa de valores que foram enviados de forma incorreta (p.e. null, "" ou email inválido) ou que excedem o tamanho máximo da coluna.

Então, antes desses dados serem salvos no banco, é preciso validá-los e ai para iniciarmos as validações vamos instalar o Validation:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-validation</artifactId>
</dependency> 
Enter fullscreen mode Exit fullscreen mode

A segunda coisa a se fazer é adicionar anotações pertinentes aos campos da classe de editora como @NotBlank nos itens que não podem ser nulos e nem vazios e @Size (max = value) para validar se o item possui tamanho equivalente a column no banco de dados.


A documentação do Bean Validation possui diversas anotações úteis, como por exemplo de e-mail, vale à pena dar uma conferida.


A classe de Editora ficou assim:
model de editora

Já o último passo é inserir a anotação @Valid nos métodos de POST e PUT lá no controlador:

methods POST and PUT

E pronto, a validação de Editora está pronta.

Testando a aplicação, quando é enviado um request com todos os dados corretos temos:
post ok

  • retorno do que foi cadastrado + id;
  • status = 201

Já quando algum item não foi enviado corretamente, temos um response gigante com várias informações:

error send request

O principal (o que considero) nessa mensagem é:

  • status = 400;
  • um defaultMessage com o motivo do erro;
  • um field com o nome do campo de erro;
  • a data e hora que ocorreu o erro.

BÔNUS: Formatando o retorno das exceções

Um bônus para você sobre como formatar o retorno das exceções ao endpoint:

P1

  • criar uma classe para o tratamento de exceções e extender a classe ResponseEntityExceptionHandler

  • a minha classe se chama ApiExceptionsHandler e está no pacote library.api.exception

  • utilizar a anotação @ControllerAdvice que, de forma simples, passa a ideia de que a classe é um componente Spring com o objetivo de tratar exceções globalmente.

  • puxar o método handleMethodArgumentNotValid

  • esse método é chamado quando ocorre algum erro que precisa ser retornado ao endpoint. Ele recebe 4 parâmetros:

  1. a exceção
  2. o cabeçalho
  3. o status e
  4. o que foi recebido pela API
  • com relação ao retorno do método escolhi o handleExceptionInternal porque ele permite retornar um objeto do tipo Object e ai esse objeto é que será a mensagem de retorno da API.

class api exceptions

P2

  • criar uma classe Field dentro do pacote library.api.exception com atributos field (String) e mensage (String)

  • adicionar as anotações do Lombok @AllArgsConstructor e @Getter

class field

  • criar a classe Error dentro do pacote library.api.exception
    e adicionar os objetos status (int), dateTime (LocalDateTime), title (String), listFields ()

  • adicionar as anotações Lombok @Getter e @Setter

class api error

P3

  • instanciar um array list do tipo Field na classe ApiExceptionHandler.

É preciso percorrer o objeto ex e para cada erro apontado pela API, pegar qual o campo que está com o erro e qual foi a defaultMessage dele. Cada item da lista de exceptions é um ObjectError e pra conseguir pegar o field é preciso do cast do tipo FieldError. Com isso, uma das possibilidades dese fazer isso é com o seguinte código:

for (ObjectError error : ex.getBindingResult().getAllErrors()) {
    String field = ((FieldError) error).getField();
    String message = error.getDefaultMessage();

    fields.add(new Field(field, message));
}
Enter fullscreen mode Exit fullscreen mode
  • na classe ApiExceptionHandler instanciar um objeto Error e setar os valores

a. status = status.value();
b. dateTime = LocalDateTime.now();
c. title = "Um ou mais campos com preenchimento inválido.";
d. listFields = o array populado anteriormente.

  • retornar o erro formatado: return handleExceptionInternal(ex, error, headers, status, request);

class api exceptions handler


Com isso temos o resultado:

  • 1 erro:
    result class api exception handler

  • mais de 1 erro:

2 result class api exception handler


Por hoje é isso!

O link do repositório no GH: clica aqui

Espero que tenha gostado, curte, compartilha e deixa ttua opinião.

Até mais!

Top comments (0)