Programação para Web 3

Organização de Aplicações Web: MVC e Spring Boot

Prof. Me. Danilo Bueno

Agenda

  1. O problema da organização
  2. O padrão MVC
  3. Frameworks e Spring Boot
  4. Criação do projeto (Spring Initializr)
  5. Execução da aplicação
  6. Controllers e rotas
  7. Model e separação de responsabilidades

O problema

Responsabilidades misturadas

Para cada requisição o servidor precisa: identificar a rota, buscar os dados, montar a resposta.

if (url.equals("/cardapio")) {    String html = "<ul>";    for (String item : buscarNoBanco("SELECT ...")) {        html += "<li>" + item + "</li>";    }    resposta.enviar(html + "</ul>");}

Três responsabilidades no mesmo bloco = código espaguete.

MVC

As três camadas do MVC

  • Model: os dados e as regras de negócio (a cozinha)
  • View: a apresentação (o prato servido)
  • Controller: a coordenação (o garçom)

MVC é um padrão de organização, não uma tecnologia.

O fluxo de uma requisição

Requisição HTTP
      ▼
[ Controller ] ── pede dados ──▶ [ Model ]
      │        ◀── devolve ─────
      ▼
  monta a resposta (View)
      ▼
Resposta HTTP

Spring Boot

O conceito de framework

Estrutura pronta: resolve o repetitivo, você escreve o específico.

  • Biblioteca: você chama o código dela
  • Framework: ele chama o seu código (inversão de controle)

Você escreve as peças; o framework as aciona na hora certa.

Uma aplicação Spring Boot mínima

@SpringBootApplicationpublic class CafeteriaApplication {    public static void main(String[] args) {        SpringApplication.run(CafeteriaApplication.class, args);    }}

Um programa Java comum que, ao rodar, vira um servidor (Tomcat embutido, porta 8080).

Spring Initializr

https://start.spring.io: o gerador oficial de projetos.

  • Maven + Java 21
  • Dependência: Spring Web
  • Gera o .zip do projeto pronto

Estrutura do projeto gerado

cafeteria/
├── pom.xml                ← dependências (Maven)
└── src/main/
    ├── java/com/exemplo/cafeteria/
    │   └── CafeteriaApplication.java
    └── resources/
        └── application.properties

Todo projeto Spring Boot segue essa mesma estrutura: convenção sobre configuração.

Execução da aplicação

Iniciando o servidor

./mvnw spring-boot:run
Tomcat started on port 8080 (http)
Started CafeteriaApplication in 1.8 s

Acesse: http://localhost:8080

localhost = a sua própria máquina.

A Whitelabel Error Page

Primeiro acesso: 404.

  • O servidor respondeu: está em execução
  • Apenas não existe rota cadastrada para /

Interpretação via HTTP: 4xx indica problema no pedido, não no servidor.

Controllers e rotas

Definindo um controller

@RestControllerpublic class CardapioController {    @GetMapping("/")    public String inicio() {        return "Bem-vindo à Cafeteria Central!";    }    @GetMapping("/cardapio")    public String cardapio() {        return "Espresso - R$ 6 | Coado - R$ 5";    }}

O retorno do método é o corpo da resposta.

Regras de mapeamento de rotas

  • Cada rota deve ser única: mapeamento duplicado impede a aplicação de iniciar
  • URL sem rota correspondente → 404
  • Alterações no código exigem reiniciar a aplicação

Definindo o Content-Type da resposta

String sai como text/plain. Para HTML:

@GetMapping(value = "/cardapio-html", produces = "text/html")public String cardapioHtml() {    return "<h1>Cardápio</h1><ul><li>Espresso</li></ul>";}

O mesmo Content-Type do DevTools: ele decide se o navegador renderiza ou mostra texto cru.

O Model

A classe de modelo

public class Bebida {    private String nome;    private double preco;    public Bebida(String nome, double preco) {        this.nome = nome;        this.preco = preco;    }    public String getNome() { return nome; }    public double getPreco() { return preco; }}

Nenhuma anotação: o modelo não sabe que HTTP existe.

A classe de repositório

public class BebidaRepository {    private List<Bebida> bebidas = List.of(        new Bebida("Espresso", 6.0),        new Bebida("Coado", 5.0)    );    public List<Bebida> listarTodas() {        return bebidas;    }}

Guarda e fornece os dados. O controller pede; ele entrega.

O controller após a separação

@RestControllerpublic class CardapioController {    private BebidaRepository repositorio = new BebidaRepository();    @GetMapping("/cardapio")    public String cardapio() {        String r = "Cardápio: ";        for (Bebida b : repositorio.listarTodas()) {            r += b.getNome() + " (R$ " + b.getPreco() + ") ";        }        return r;    }}

Mudar os dados → repositório. Mudar a rota → controller.

Referência rápida

Item Papel
MVC Model = dados, View = exibição, Controller = coordenação
Spring Initializr Gera o projeto (start.spring.io)
./mvnw spring-boot:run Sobe o servidor (Tomcat, porta 8080)
@RestController Retornos vão direto no corpo da resposta
@GetMapping("/x") Liga método a GET /x
produces = "text/html" Define o Content-Type da rota
Repositório Classe que guarda/fornece os dados

Obrigado!

Prof. Me. Danilo Bueno
[email protected]