Até agora fizemos uma aplicação que exibe uma lista de produtos e mostra os detalhes de cada um deles. Agora vamos adicionar a funcionalidade de atualizar um produto.
Para isso, vamos adicionar um link na página de detalhes de um produto que leva para uma página de formulário para atualizar o produto. Essa página vai ter um formulário com os dados do produto e um botão para enviar o formulário.
Nessa etapa vamos juntar os conhecimentos aprendidos anteriormente para conseguir fazer essa funcionalidade. Vamos começar criando uma nova rota para a página de formulário de atualização de produto usando a visão list
que vai ser bem similar a que usamos para detalhar o produto, mudando apenas o nome da página.
1<td>2 <a th:href="@{/products/show(id = ${product.id})}">Show</a>3 <a th:href="@{/products/edit(id = ${product.id})}">Edit</a>4</td>
Agora precisamos criar a rota para essa página que deve receber o parâmetro id
que vai ser o id do produto que queremos atualizar. Vamos criar um novo método no nosso controller para essa rota.
1 @GetMapping("/products/edit")2 public String edit(Model model, @RequestParam("id") String id){3 Product product = findProductById(id);4 model.addAttribute("product", product);5 return "edit";6 }
Perceba que o método é bem similar ao método show
que criamos anteriormente, com a mesma lógica de recupear o id
passado via URL, fazer a busca do produto na lista de produtos, adicionar esse produto no container da visão e retornar o nome da visão, que nesse caso chamamos de edit
pois é uma nova página.
Vamos criar essa nova página edit.html
na pasta src/main/resources/templates
. A ideia é que essa página seja bem similar a página create
que criamos anteriormente, com um formulário para atualizar o produto, só que dessa vez um formulário populado com os dados daquele produto em questão.
1<form method="post" th:action="@{/products/update}">2
3 <input type="hidden" th:field="${product.id}" id="id">4
5 <label for="name">Nome</label>6 <input type="text" th:field="${product.name}" id="name">7
8 <label for="description">Descrição</label>9 <input type="text" th:field="${product.description}" id="description">10
11 <label for="price">Preço</label>12 <input type="text" th:field="${product.price}" id="price">13
14 <button type="submit">Salvar</button>15</form>
Temos 2 modificações importantes nesse formulário em comparação ao formulário de novo produto. A primeira é que adicionamos um campo hidden
para o id
do produto. Esse campo é necessário para que o Spring consiga identificar qual produto estamos atualizando. A segunda modificação é a rota, que em vez de apontar para store
agora aponta para update
. Ou seja, em vez de apenas cadastrar esse novo produto, vamos atualizar um produto já existente.
A última parte do nosso trabalho é criar a rota para atualizar o produto. Vamos criar um novo método no nosso controller para essa rota.
1 @PostMapping("/products/update")2 public String update(Product product){3 Product productToUpdate = findProductById(product.getId());4 productToUpdate.setName(product.getName());5 productToUpdate.setDescription(product.getDescription());6 productToUpdate.setPrice(product.getPrice());7 return "redirect:/products";8 }
Nessa rota temos mapeado o método Post
pois os dados estão vindo diretamente do formulário e não via URL. Além disso, temos um parâmetro Product
que é o produto que estamos atualizando. Esse parâmetro é preenchido automaticamente pelo Spring com os dados do formulário, pois os campos do formulário tem o mesmo nome dos atributos da classe Product
.
A partir desses dados, fazemos a busca do produto na lista de produtos e atualizamos os dados desse produto com os dados que vieram do formulário. Por fim, retornamos um redirecionamento para a página de listagem de produtos. Teste no navegador e verá que agora é possível atualizar um produto.