Search buenodc

Nesta página
  1. Importante
  2. Contextualização
  3. Como começar
  4. Como funciona
  5. Cronograma
  6. Missão 1: O servidor da loja no ar
  7. Missão 2: As primeiras rotas
  8. Missão 3: Os livros entram em cena
  9. Missão 4: Separando as camadas
  10. Entrega individual

Atividade MVC e Spring Boot (EstanteWeb)

Disciplina: Programação para Web 3
Assunto: Organização de aplicações Web (MVC, Spring Boot, Controllers e rotas)
Professor: Prof. Me. Danilo Bueno
Grupos: duplas
Duração: 4 aulas de 50 minutos (em sala)


Importante

Antes de começar, leia o material de apoio sobre MVC e Spring Boot. É imprescindível ler antes de codar: a atividade aplica exatamente os conceitos do material. Se tiver dúvidas, releia, pergunte ao professor ou aos colegas. Você também pode consultar os slides da aula.


Contextualização

A EstanteWeb é um sebo de bairro que vende livros usados. O acervo inteiro vive num caderno: quando um cliente telefona perguntando se determinado título existe, alguém folheia páginas à mão. A dona decidiu levar a loja para a Web e contratou você e sua dupla como a equipe de desenvolvimento.

O sistema será construído do jeito certo desde o início: organizado. Nesta primeira etapa, a missão da dupla é colocar o servidor da loja no ar e estruturar a aplicação em camadas: controllers atendendo rotas e um modelo guardando os primeiros livros do acervo.

Este é o começo de verdade: o projeto que vocês criam hoje é a fundação do sistema da EstanteWeb.


Como começar

Cada dupla precisa de uma máquina com:

  1. Java (JDK) 21: a versão da linguagem é fixa na disciplina. Se precisar instalar, use uma distribuição gratuita como o Eclipse Temurin 21.
  2. VS Code com a extensão Extension Pack for Java (instale pela aba de extensões).
  3. Acesso ao site https://start.spring.io (Spring Initializr): é lá que o projeto nasce, na Missão 1.

Antes de começar, verifique as ferramentas. Abra o terminal e rode os comandos abaixo; cada um deve responder sem erro de “comando não encontrado”:

java -version     # deve exibir a versão 21 (ex.: openjdk 21.x)
code --version    # confirma o VS Code no PATH (ou abra pelo menu normalmente)
mvn -version      # opcional: o projeto traz o Maven wrapper (mvnw), que dispensa o Maven instalado

Se java -version mostrar outra versão (8, 11, 17…), instale o JDK 21 antes de seguir. Chame o professor se travar aqui: nada da atividade funciona sem o Java certo.

Não há código para copiar: o projeto será gerado pelo Spring Initializr na Missão 1, com estas opções:

CampoValor
ProjectMaven
LanguageJava
Spring Bootversão estável sugerida
Groupbr.com.estanteweb
Artifactestanteweb
Package namebr.com.estanteweb
Java21
DependenciesSpring Web

Guarde bem este projeto ao final da atividade (a pasta inteira): ele é o sistema da loja, e é sobre ele que o trabalho continua.


Como funciona

  • A atividade é feita em dupla, mas as entregas no Moodle são individuais.
  • As missões são incrementais: cada uma constrói sobre a anterior, siga na ordem.
  • Ao final de cada missão, teste no navegador (e, quando indicado, no DevTools) antes de seguir.
  • Responda, no caminho, às perguntas em destaque (marcadas com >). Elas voltam no questionário do Moodle.

Cronograma

AulaFocoMissões
1Ambiente, Initializr e servidor no arMissão 1
2Primeiras rotasMissão 2
3O modelo: os livros do acervoMissão 3
4Separação em camadas + desafioMissão 4

Missão 1: O servidor da loja no ar

Objetivo: gerar o projeto, abri-lo na IDE e ver o servidor respondendo.

1.1. Acesse https://start.spring.io e preencha exatamente as opções da tabela em “Como começar” (confira o Package name br.com.estanteweb, o Java 21 e a dependência Spring Web). Clique em Generate, descompacte o .zip numa pasta sua e abra a pasta do projeto no VS Code (File, Open Folder).

1.2. Localize a classe EstantewebApplication e execute a aplicação (botão Run que a extensão Java mostra sobre o método main, ou ./mvnw spring-boot:run no terminal, na pasta do projeto). No console, encontre e anote a linha que indica em qual porta o servidor subiu.

1.3. Acesse http://localhost:8080 no navegador. Você verá a Whitelabel Error Page. Abra o DevTools (F12 → Network), recarregue e registre o código de status dessa resposta.

O servidor acabou de subir e a página inicial mostra um erro 404. Isso significa que a aplicação está quebrada? Explique o que esse 404 diz sobre o servidor e sobre a rota /.


Missão 2: As primeiras rotas

Objetivo: criar o primeiro controller e ensinar o servidor a responder.

2.1. No pacote br.com.estanteweb (ao lado da classe EstantewebApplication), crie a classe PaginaController anotada com @RestController, com um método mapeado em / (via @GetMapping) retornando uma mensagem de boas-vindas da loja, por exemplo: "EstanteWeb: livros usados com história". Reinicie a aplicação e confira no navegador que o 404 da Missão 1 virou 200 com a sua mensagem (abra novamente o devtools para checar o código).

2.2. No mesmo controller, crie a rota /sobre, retornando uma frase que descreva a loja. Teste no navegador.

2.3. Experimente o erro clássico: crie temporariamente um segundo método também mapeado em /sobre e tente rodar a aplicação. Observe o que acontece no console, registre a mensagem de erro e então desfaça (apague o método duplicado).

O que aconteceu quando duas rotas iguais existiram ao mesmo tempo: o erro apareceu ao acessar a página ou ao subir a aplicação? Por que esse comportamento é melhor do que descobrir o problema só quando um cliente acessasse?


Missão 3: Os livros entram em cena

Objetivo: criar o modelo do acervo e exibi-lo numa rota.

3.1. Crie a classe Livro (o modelo), com os atributos titulo, autor, ano e preco, construtor e getters. Ela não deve ter nada de HTTP: nenhuma anotação de rota.

3.2. Crie a classe LivroController com a rota /livros. Por enquanto, dentro do controller, monte uma List<Livro> com os 5 primeiros livros do acervo (invente títulos de livros usados) e retorne uma String listando título, autor e preço de cada um, percorrendo a lista com um laço.

Ao acessar http://localhost:8080/livros, a resposta deve seguir este formato (os títulos serão os que sua dupla inventou, não estes):

Acervo EstanteWeb: Dom Casmurro, de Machado de Assis (R$ 24.9) | A Hora da Estrela, de Clarice Lispector (R$ 22.0) | ...

3.3. Acrescente a rota /livros/total, que retorna quantos livros existem no acervo (use o tamanho da lista; cuidado para não escrever o número “na mão”).

Ao acessar http://localhost:8080/livros/total, a resposta deve seguir este formato (o número deve bater com a quantidade de livros que você colocou na lista):

O acervo tem 5 livros.

A classe Livro ficou sem nenhuma anotação do Spring. O que ela representa no MVC, e por que ela não deve saber nada sobre rotas ou HTTP?


Missão 4: Separando as camadas

Objetivo: tirar os dados de dentro do controller e concluir a organização MVC da semana.

4.1. Crie a classe LivroRepository, com a lista de livros da Missão 3 movida para dentro dela e um método listarTodos() que a retorna. O LivroController passa a criar um LivroRepository e a usá-lo; nenhuma lista de livros pode sobrar no controller.

4.2. Adicione ao repositório o método contarLivros() e faça a rota /livros/total usá-lo. Confira no navegador que as duas rotas continuam funcionando exatamente como antes da mudança.

4.3. Adicione ao acervo um livro cujo título contenha uma tag HTML, por exemplo O <b>Grande</b> Gatsby, e observe como ele aparece na rota /livros.

4.4. Desafio (opcional): crie a rota /livros/html com produces = "text/html", retornando o acervo como uma lista HTML (<ul>/<li>). Compare no navegador com a rota /livros e, no DevTools, compare o Content-Type das duas respostas.

Na rota /livros (texto puro), a tag <b> do título apareceu escrita na tela; na /livros/html, o navegador a interpretou. Qual header da resposta explica essa diferença de comportamento?


Entrega individual

Cada integrante da dupla deve, individualmente, no Moodle:

  1. Responder o questionário da semana (perguntas de reflexão sobre a atividade).
  2. Enviar o projeto compactado em .zip (a pasta do projeto sem a subpasta target/, que é gerada na compilação e pesa à toa).