📚 Pré-requisitos Teóricos: Este projeto prático aplica os fundamentos do padrão arquitetural MVC, mapeamento objeto-relacional com Spring Data JPA e renderização com Thymeleaf ensinados na Especialização em Backend com Java e Spring Boot.
A Biblioteca de Jogos (v1) estabelece a fundação do desenvolvimento web corporativo com Spring Boot 3. O projeto implementa um catálogo completo de jogos digitais abrangendo as operações de cadastro, listagem dinâmica, alternância de status de conclusão (“zerado”) e exclusão de registros, utilizando banco de dados H2 em desenvolvimento e persistência relacional.
O diagrama a seguir descreve o fluxo de requisições web entre a camada de visualização Thymeleaf, o controlador Spring MVC e o repositório JPA:
A base de código segue o padrão canônico com nomenclatura anti-colisão:
catalogo_projetos/javaweb_jogos_01_crud/
├── assets/ # Galeria de diagramas visuais e arquitetura
│ └── arquitetura_jogos_crud.svg
├── web-spring/ # Aplicação Spring Boot 3 MVC
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/br/com/bibliotecajogos/
│ │ │ │ ├── controller/ # JogoController (rotas web /jogos)
│ │ │ │ ├── entity/ # Jogo (Entidade JPA)
│ │ │ │ └── repository/ # JogoRepository (Spring Data JPA)
│ │ │ └── resources/
│ │ │ ├── templates/
│ │ │ │ └── index.html # View Thymeleaf com Bootstrap 5
│ │ │ └── application.properties
│ │ └── test/ # Testes unitários do contexto
│ ├── Dockerfile
│ ├── pom.xml
│ ├── mvnw
│ └── mvnw.cmd
└── index.md # Especificação executiva e Padrão Ouro
| ID | Persona | História de Usuário | Prioridade |
|---|---|---|---|
| US-01 | Gamer / Colecionador | Desejo cadastrar novos títulos na minha biblioteca informando nome, plataforma e gênero. | Alta |
| US-02 | Gamer / Colecionador | Desejo visualizar todos os jogos cadastrados com seus respectivos estados de progresso. | Alta |
| US-03 | Gamer / Colecionador | Desejo alternar rapidamente o status do jogo para “concluído/zerado” com um clique. | Média |
| US-04 | Gamer / Colecionador | Desejo remover títulos indesejados da biblioteca de forma simples e intuitiva. | Média |
| US-05 | Desenvolvedor Júnior | Desejo compreender a integração direta entre Controller e Repository no ecossistema Spring. | Alta |
| ID | Nome | Descrição |
|---|---|---|
| RF-01 | Listagem Geral | Rota GET / renderizando a tabela de jogos cadastrados via template Thymeleaf. |
| RF-02 | Cadastro de Jogo | Rota POST /jogos persistindo novo objeto Jogo a partir dos dados do formulário. |
| RF-03 | Alternar Status | Rota POST /jogos/{id}/concluir invertendo o valor booleano do atributo concluido. |
| RF-04 | Exclusão de Registro | Rota POST /jogos/{id}/apagar removendo o jogo correspondente pelo identificador único. |
| RF-05 | Interface Responsiva | Renderização de cards e tabelas estilizadas com Bootstrap 5 sem dependência de JavaScript pesado. |
| ID | Nome | Descrição |
|---|---|---|
| RNF-01 | Desempenho de Carga | Renderização da página inicial no servidor executada em menos de 100ms. |
| RNF-02 | Simplicidade Arquitetural | Aderência aos conceitos fundamentais de Spring MVC para fins pedagógicos. |
| RNF-03 | Integridade dos Dados | Chave primária auto-incremental gerenciada pelo banco com GenerationType.IDENTITY. |
| RNF-04 | Portabilidade Multi-Ambiente | Suporte a banco H2 em memória no perfil local e PostgreSQL em produção. |
| RNF-05 | Empacotamento Docker | Imagem OCI construída com Maven Wrapper garantindo reproducibilidade de build. |
flowchart TD
subgraph Ator
USR["Gamer / Usuário"]
end
subgraph "Biblioteca de Jogos v1 (web-spring)"
UC1["Visualizar Lista de Jogos (GET /)"]
UC2["Cadastrar Novo Jogo (POST /jogos)"]
UC3["Marcar como Concluído (POST /{id}/concluir)"]
UC4["Remover Jogo (POST /{id}/apagar)"]
end
USR --> UC1
USR --> UC2
USR --> UC3
USR --> UC4
| Requisito Funcional | Histórias Atendidas | Requisitos Não-Funcionais | Status de Cobertura |
|---|---|---|---|
| RF-01 (Listagem Geral) | US-02 | RNF-01, RNF-02 | Implementado ✅ |
| RF-02 (Cadastro de Jogo) | US-01 | RNF-02, RNF-03 | Implementado ✅ |
| RF-03 (Alternar Status) | US-03 | RNF-01, RNF-03 | Implementado ✅ |
| RF-04 (Exclusão) | US-04 | RNF-02, RNF-03 | Implementado ✅ |
| RF-05 (Interface Bootstrap) | US-02, US-05 | RNF-01, RNF-04 | Implementado ✅ |
Jogo.java)@Entity
@Table(name = "jogos")
public class Jogo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String titulo;
private String plataforma;
private boolean concluido;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitulo() { return titulo; }
public void setTitulo(String titulo) { this.titulo = titulo; }
public String getPlataforma() { return plataforma; }
public void setPlataforma(String plataforma) { this.plataforma = plataforma; }
public boolean isConcluido() { return concluido; }
public void setConcluido(boolean concluido) { this.concluido = concluido; }
}
JogoController.java)📄 web-spring/src/main/java/br/com/bibliotecajogos/controller/JogoController.java (arquivo real do projeto)
package br.com.bibliotecajogos.controller;
import br.com.bibliotecajogos.entity.Jogo;
import br.com.bibliotecajogos.repository.JogoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
public class JogoController {
@Autowired
private JogoRepository jogoRepository;
@GetMapping("/")
public String listar(Model model) {
model.addAttribute("jogos", jogoRepository.findAll());
model.addAttribute("novoJogo", new Jogo());
return "jogos";
}
@PostMapping("/jogos")
public String adicionar(@ModelAttribute Jogo novoJogo) {
jogoRepository.save(novoJogo);
return "redirect:/";
}
@PostMapping("/jogos/{id}/concluir")
public String marcarConcluido(@PathVariable Long id) {
jogoRepository.findById(id).ifPresent(jogo -> {
jogo.setConcluido(!jogo.isConcluido());
jogoRepository.save(jogo);
});
return "redirect:/";
}
@PostMapping("/jogos/{id}/apagar")
public String apagar(@PathVariable Long id) {
jogoRepository.deleteById(id);
return "redirect:/";
}
}
cd catalogo_projetos/javaweb_jogos_01_crud/web-spring
./mvnw spring-boot:run
No Windows (PowerShell):
cd catalogo_projetos\javaweb_jogos_01_crud\web-spring
.\mvnw.cmd spring-boot:run
http://localhost:8080/.| Checkpoint | Critério de Aceite | Validação | Status |
|---|---|---|---|
| CP-01 | Inicialização bem-sucedida do contexto Spring Boot 3 | Aplicação respondendo na porta 8080 | PASS ✅ |
| CP-02 | Renderização da listagem de jogos com Thymeleaf | Template HTML processado sem erros de parsing | PASS ✅ |
| CP-03 | Persistência de novo registro através de formulário POST | Registro gravado no banco relacional | PASS ✅ |
| CP-04 | Atualização de status booleano via endpoint dedicado | Estado invertido e refletido na interface | PASS ✅ |
| CP-05 | Exclusão física de registros por identificador | Entidade removida da tabela e view atualizada | PASS ✅ |