Search buenodc

Nesta página
  1. Importante
  2. Contextualização
  3. O que já temos
  4. Como começar
  5. Como funciona
  6. Cronograma
  7. Missão 1: O formulário de cadastro
  8. Missão 2: Gravando no banco
  9. Missão 3: Validação e fluxo de navegação
  10. Missão 4: Cadastro de sugestões + desafio
  11. Entrega individual

Atividade Cadastro de Informações (EstanteWeb)

Disciplina: Programação para Web 3
Assunto: INSERT, formulários de cadastro e persistência de dados
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 cadastro de informações. É 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

Desde a semana passada, o acervo exibido no site vem de verdade do banco de dados. Mas a dona da EstanteWeb ainda não consegue cadastrar um livro novo: para incluir qualquer título, alguém precisa abrir o terminal do MySQL e escrever um INSERT à mão. Nesta etapa, a dupla vai construir a tela de cadastro do acervo, com validação e gravação real no banco, encerrando a dependência do terminal.


O que já temos

O checkpoint de partida (semana-08-inicio) traz a aplicação Spring Boot das semanas anteriores, já rodando em http://localhost:8080, com:

  • LivroRepository (@Repository), com @Autowired JdbcTemplate e os métodos de consulta: listarTodos(), contarLivros(), listarAtePreco(double) e somarValorAcervo().
  • Livro, com construtor sem argumentos, getters, setters e o método estático deMap(Map).
  • LivroController (@Controller), com as rotas do acervo, entre elas /livros/html, que exibe a listagem pelo template livros.ftlh.
  • Templates cabecalho.ftlh, livros.ftlh, contato.ftlh, contato-sucesso.ftlh e sugestao-nova.ftlh, todos já com <#include> do cabeçalho.
  • Banco MySQL com a tabela livro populada.

Como começar

  1. git clone do repositório do projeto (pule este passo se sua dupla já clonou nas semanas anteriores).
  2. git checkout semana-08-inicio para partir exatamente do estado descrito acima.
  3. Confirme que o container MySQL está no ar (docker ps). Se não estiver, suba-o com docker start estanteweb-mysql.
  4. Rode a aplicação e confirme que http://localhost:8080/livros/html exibe o acervo vindo do banco.

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 antes de seguir.
  • Responda, no caminho, às perguntas em destaque (marcadas com >). Elas voltam no questionário do Moodle.

Cronograma

AulaFocoMissões
1O formulário de cadastroMissão 1
2Gravando no banco com updateMissão 2
3Validação e fluxo de navegaçãoMissão 3
4Cadastro de sugestões + desafioMissão 4

Missão 1: O formulário de cadastro

Objetivo: criar a tela que coleta os dados de um novo livro, sem ainda gravá-la.

1.1. Crie o template livro-novo.ftlh, com <#include "cabecalho.ftlh"> no topo e um <form method="post" action="/livros"> contendo quatro campos de texto: titulo, autor, ano e preco, além do botão de envio. Use value="${titulo!}" (e equivalentes) em cada campo.

1.2. Em LivroController, crie a rota GET /livros/novo, que apenas retorna "livro-novo".

1.3. Acesse http://localhost:8080/livros/novo e confirme que o formulário aparece. Clique em enviar e observe o erro retornado: ainda não existe nenhuma rota que receba esse POST.

O formulário aponta para /livros no atributo action, mas essa rota já existe como GET. Por que o envio não caiu na rota de listagem que já estava lá?


Missão 2: Gravando no banco

Objetivo: criar o método que insere um livro e a rota que o utiliza.

2.1. Em LivroRepository, crie o método salvar(Livro livro), que executa INSERT INTO livro (titulo, autor, ano, preco) VALUES (?, ?, ?, ?) com jdbcTemplate.update(...), passando os quatro valores na ordem correta.

2.2. Em LivroController, crie a rota POST /livros, recebendo titulo, autor, ano (tipo int) e preco (tipo double) via @RequestParam. Monte um Livro com os setters, chame repositorio.salvar(livro) e, por enquanto, retorne "redirect:/livros/html".

2.3. Cadastre um livro pelo formulário e confirme que ele aparece na listagem. Confirme também pelo terminal do MySQL, com SELECT * FROM livro;.

O INSERT não informa a coluna id, mas o livro cadastrado apareceu com um id preenchido no banco. Quem atribuiu esse valor, e com base em que definição feita na Semana 6?


Missão 3: Validação e fluxo de navegação

Objetivo: impedir cadastros inválidos e devolver o formulário preenchido quando houver erro.

3.1. No POST /livros, antes de gravar, valide os dados: se titulo ou autor vierem em branco, ou se preco for menor ou igual a zero, adicione ao Model um atributo erro com a mensagem adequada, reenvie os valores digitados (titulo, autor, ano, preco) e retorne "livro-novo".

3.2. Ajuste livro-novo.ftlh para exibir a mensagem de erro apenas quando ela existir, usando <#if erro??>.

3.3. Teste os dois caminhos: envie o formulário com o título em branco (deve voltar com o erro e os demais campos preenchidos) e depois com todos os campos válidos (deve gravar e redirecionar para a listagem).

Por que a validação precisa acontecer antes da chamada a repositorio.salvar(...), e não depois? O que aconteceria com um dado inválido que chegasse ao banco?


Missão 4: Cadastro de sugestões + desafio

Objetivo: aplicar o mesmo padrão à sugestão de leitura, que até agora só existia em memória.

4.1. Em SugestaoRepository, adicione @Repository à classe e um campo @Autowired JdbcTemplate, mantendo a lista em memória por enquanto, como feito na Semana 7 com o LivroRepository.

4.2. Crie o método salvar(Sugestao sugestao), executando INSERT INTO sugestao (nome_cliente, livro_sugerido) VALUES (?, ?) com jdbcTemplate.update(...). A tabela sugestao já existe desde a Semana 6.

4.3. Em SugestaoController, troque a chamada repositorio.adicionar(...) por repositorio.salvar(...) no POST /sugestoes. Envie uma sugestão pelo formulário e confirme, pelo terminal do MySQL, que a linha foi gravada na tabela.

4.4. Desafio (opcional): faça a listagem de sugestões (GET /sugestoes) passar a ler do banco, criando o método listarTodas() com queryForList e um Sugestao.deMap(Map), no mesmo formato usado no Livro. Remova então a lista em memória de SugestaoRepository. Reinicie a aplicação e confirme que as sugestões enviadas antes do reinício continuam aparecendo.

No desafio, as sugestões passaram a sobreviver ao reinício da aplicação. Compare com o comportamento observado na Semana 3, quando essa mesma listagem foi criada: o que mudou?


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).