Neste codelab você aprenderá a tratar erros em sua aplicação web utilizando o framework Spring Boot com Thymeleaf e acesso a dados com JdbcTemplate.
Clonar o projeto neste repositório GitHub e adicionar tratamento de erros.
@ControllerAdvice@ExceptionHandlerUma característica comum em todos programas de computador é a necessidade de tratar exceções. Em Java as exceções são tratadas por um mecanismo de lançamento de exceções quando o erro é identificado. Spring Boot oferece diversas maneiras de tratar exceções. Uma forma simples e poderosa que usaremos aqui neste tutorial é a anotação @ControllerAdvice.
Esta anotação facilita nossa vida para lidar com todos os tipos de exceções em um local central em nossa aplicação. A facilidade está em não precisar capturar exceções em cada método ou classe separadamente, bastando apenas lançar a exceção no método e, em seguida, ela será capturada na classe central de tratamento de exceções anotada por @ControllerAdvice.
Divisão por zero - java.lang.ArithmeticException: / by zero
public class Teste {
public static void main(String[] args) {
System.out.println("chamando m1()");
m1();
System.out.println("fim do método main");
}
private static void m1() {
System.out.println("chamando m2()");
m2();
System.out.println("fim do método m1()");
}
private static void m2() {
System.out.println("início do m2()");
int x = 1 / 0;
System.out.println("fim do método m2()");
}
}
Depois de executar o programa acima teremos o seguinte:

Como tratar este erro? Vamos modificar o código anterior para exemplificar
package com.professorangoti.condominio;
public class Teste {
public static void main(String[] args) {
System.out.println("chamando m1()");
m1();
System.out.println("fim do método main");
}
private static void m1() {
System.out.println("chamando m2()");
m2();
System.out.println("fim do método m1()");
}
private static void m2() {
System.out.println("início do m2()");
try { // colocar o código com potencial de erro dentro do bloco try
int x = 1 / 0;
} catch (ArithmeticException e) { //capturar as exceções que podem ocorrer
System.out.println("Erro: " + e.getMessage());
}
System.out.println("fim do método m2()");
}
}
Depois de executar o programa acima teremos o seguinte:

O bloco try/catch não deixa o programa parar, tratando o erro no local onde aconteceu. Se as exceções capturadas forem de mesma hierarquia, as classes mais especializadas devem aparecer primeiro. Para capturar qualquer exceção use a classe Exception (não indicado):
catch (Exception e) { ... }
Podemos também delegar o tratamento do erro para outro método na pilha de execução, para isso podemos lançar uma exceção .
A classe que será criada para fazer o papel de central de tratamento de exceções deverá ser anotada com a anotação @ControllerAdvice. Nesta classe vamos usar a seguinte anotação em seus métodos:
@ExceptionHandler: você deverá fornecer as exceções tratadas pelo métodoEsta anotação vai funcionar como um filtro para capturar uma exceção específica, possibilitando o tratamento do erro.
Classe MyControllerAdvice
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@ControllerAdvice
public class MyControllerAdvice {
@ExceptionHandler(java.sql.SQLIntegrityConstraintViolationException.class)
public String violaçãoDeIntegridade(java.sql.SQLIntegrityConstraintViolationException ex,
final RedirectAttributes redirectAttributes) {
String errorMessage = ex.getMessage();
if (errorMessage.contains("Cannot delete or update a parent row")) {
redirectAttributes.addFlashAttribute("mensagem", "O proprietário tem apartamento cadastrado. Não é possível excluí-lo do sistema");
return "redirect:/rel_prop";
}
return "error";
}
}
Esta classe deve estar no mesmo pacote das classes controladoras (pacote controller).
Precisamos alterar o template rel_prop.html para exibir a mensagem de erro:
<!DOCTYPE html>
<html th:include="template :: modelo">
<body>
<div th:fragment="conteudo">
<div th:if="${mensagem}" th:text="${mensagem}" class="p-3 mb-2 bg-warning text-dark">
</div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Nome</th>
<th scope="col">Telefone</th>
<th scope="col">Ações</th>
</tr>
</thead>
<tbody>
<tr th:each="prop : ${proprietarios}">
<th scope="row" th:text="${prop.id}"></th>
<td th:text="${prop.nome}"></td>
<td th:text="${prop.telefone}"></td>
<td>
<a th:href="@{/excluir_prop(id=*{prop.id})}">Excluir</a>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>