3
respostas

Metodo editar redirecionando para um form-update, editando os produtos no banco de dados

Para ter um destaque maior na minha pergunta resolvi criar um tópico novo!

Consegui fazer o remover, ao clicar no link remover o produto é removido do banco de dados. Segue o que eu fiz: Metodo da classe ProdutosController

@RequestMapping(method = RequestMethod.GET, value = "remover/{id}")
    public String remover(@PathVariable("id") Integer id) {
        produtoDao.remover(id);
        return "redirect:/produtos";
    }

classe ProdutoDAO

public void remover(Integer id) {
        manager.remove(findById(id));
    }

link com a pagina de listagem lista.jsp

<c:forEach items="${produtos }" var="produto">
            <tr>
                <td>
                    <a href="${s:mvcUrl('PC#detalhe').arg(0,produto.id).build() }">${produto.titulo }</a>
                </td>
                <td>${produto.descricao }</td>
                <td>${produto.precos }</td>
                <td>${produto.paginas }</td>
                <td>        
<a href="<c:url value='produtos/remover'/>/${produto.id}">Remover</a>
                </td>  
            </tr>
        </c:forEach>

Porém continuo com dificuldade com o Editar, nao sei como fazer para redirecionar exibindo os dados do produto num form de update

Segue os códigos:

classe ProdutosController

@RequestMapping(method = RequestMethod.POST, value = "produtos/{id}/form")
    public ModelAndView atualizar(@PathVariable("id") Integer id, @Valid Produto produto, BindingResult result) {
        if (result.hasErrors()) {
            return form(produto);
        }
        produtoDao.atualizar(produto);
        return new ModelAndView("redirect:produtos/form-update");
    }

classe ProdutoDAO

public void atualizar(Produto produto) {
        manager.merge(produto);
    }

link na listagem de produtos lista.jsp

<c:forEach items="${produtos }" var="produto">
            <tr>
                <td>
                    <a href="${s:mvcUrl('PC#detalhe').arg(0,produto.id).build() }">${produto.titulo }</a>
                </td>
                <td>${produto.descricao }</td>
                <td>${produto.precos }</td>
                <td>${produto.paginas }</td>
                <td>        
                <a href="<c:url value='produtos/${produto.id}/form'/>">Alterar</a>
                <a href="<c:url value='produtos/remover'/>/${produto.id}">Remover</a>
                </td>  
            </tr>
        </c:forEach>
    </table>

E a página form-update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Livro de Java, Android, iPhone, Ruby, PHP e muito mais - Livraria do Programador</title>

<c:url value="/resources/css" var="cssPath" />
<link rel="stylesheet" href="${cssPath }/bootstrap.min.css">
<link rel="stylesheet" href="${cssPath }/bootstrap-theme.min.css">

<style type="text/css">
    body {
        padding: 60px 0px;
    }
</style>

</head>
<body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="${s:mvcUrl('HC#index').build() }">Livraria do Programador</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li><a href="${s:mvcUrl('PC#listar').build() }">Lista de Produtos</a></li>
            <li><a href="${s:mvcUrl('PC#form').build() }">Cadastro de Produtos</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">

    <h1>atualizar produto</h1>

    <form:form action="${s:mvcUrl('PC#atualizar').build() }" method="PUT"
            commandName="produto" enctype="multipart/form-data">
        <div class="form-group">
            <label>Titulo</label>
            <form:input path="titulo" cssClass="form-control" />
            <form:errors path="titulo" />
        </div>
        <div class="form-group">
            <label>Descição</label>
            <form:textarea path="descricao" cssClass="form-control" />
            <form:errors path="descricao" />
        </div>
        <div class="form-group">
            <label>Páginas</label>
            <form:input path="paginas" cssClass="form-control"/>
            <form:errors path="paginas" />
        </div>
        <div class="form-group">
            <label>Data de Lançamento</label>
            <form:input path="dataLancamento" cssClass="form-control"/>
            <form:errors path="dataLancamento"/>
        </div>
        <c:forEach items="${tipos }" var="tipoPreco" varStatus="status">
            <div class="form-group">
                <label>${tipoPreco }</label>
                <form:input path="precos[${status.index }].valor" cssClass="form-control" />
                <form:hidden path="precos[${status.index }].tipo" value="${tipoPreco }" />
            </div>
        </c:forEach>
        <button type="submit" class="btn btn-primary">Atualizar</button>
    </form:form>

    </div>

</body>
</html>
3 respostas

Você precisa de um método no controller que seja configuração para aquela url que vc colocou no link. Nesse método vc vai carregar o produto pelo id e retorna um modelandview com esse produto associado a chave produto, direcionando para a página de atualização.

Lembre que não é um redirect, apenas indique a página que deve ser chamada.

Tentei implementar , porém ainda estou tendo problemas. Ao clicar no link "Alterar" de algum produto, é direcionado para a página de alterar dados do produto, porém não consigo passar a essa página os dados do produto, os form ficam vazios. Com os forms vazios eu tento editar os valores e ao final clico no botão "Atualizar", era pra ser redirecionado para a listagem de produtos cos os valores alterados, mas é direcionado para pagina de erro genérico, ao acessar a página de listagem de produtos, os produtos são excluídos. Vendos os logs do console do eclipse antes de ocorrer a página de erro genérico é feito o update dos produtos e logo após um delete. Gostaria que me ajudassem a implementar esse alterar, pois já estou quase desistindo do projeto :(

Segue os códigos:

método da classe produtoscontroller referenciando a página form2

    @RequestMapping("form2/{id}")
    public ModelAndView atualizar(Produto produto) {

        ModelAndView modelAndView = new ModelAndView("produtos/form2");
        modelAndView.addObject("tipos", TipoPreco.values());
        produtoDao.atualizar(produto);
        return modelAndView;
    }

foreach da pagina de listagem de produtos lista.jsp

<c:forEach items="${produtos }" var="produto">
            <tr>
                <td>
                    <a href="${s:mvcUrl('PC#detalhe').arg(0,produto.id).build() }">${produto.titulo }</a>
                </td>
                <td>${produto.descricao }</td>
                <td>${produto.precos }</td>
                <td>${produto.paginas }</td>
                <td>        
                <a href="<c:url value='produtos/form2'/>/${produto.id}">Alterar</a>
                <a href="<c:url value='produtos/remover'/>/${produto.id}">Remover</a>
                </td>  
            </tr>
        </c:forEach>

pagina form2.jsp

<%@ page contentType="text/html; charset=ISO-8859-1" language="java" pageEncoding="UTF-8" import="java.sql.*" errorPage="" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta charset="UTF-8">
<title>Livro de Java, Android, iPhone, Ruby, PHP e muito mais - Livraria do Programador</title>

<c:url value="/resources/css" var="cssPath" />
<link rel="stylesheet" href="${cssPath }/bootstrap.min.css">
<link rel="stylesheet" href="${cssPath }/bootstrap-theme.min.css">

<style type="text/css">
    body {
        padding: 60px 0px;
    }
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="${s:mvcUrl('HC#index').build() }">Livraria do Programador</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li><a href="${s:mvcUrl('PC#listar').build() }">Lista de Produtos</a></li>
            <li><a href="${s:mvcUrl('PC#form').build() }">Cadastro de Produtos</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">

    <h1>Alterar Dados de Produto</h1>

    <form:form action="${s:mvcUrl('PC#atualizar').build() }" accept-charset="iso-8859-1,utf-8" method="POST" modelAttribute="produtos"
            commandName="produto" enctype="multipart/form-data"> 

        <div class="form-group">
            <label>Titulo</label>
            <form:input path="titulo" cssClass="form-control" />
            <form:errors path="titulo" />
        </div>
        <div class="form-group">
            <label>Descição</label>
            <form:textarea path="descricao" cssClass="form-control" />
            <form:errors path="descricao" />
        </div>
        <div class="form-group">
            <label>Páginas</label>
            <form:input path="paginas" cssClass="form-control"/>
            <form:errors path="paginas" />
        </div>
        <div class="form-group">
            <label>Data de Lançamento</label>
            <form:input path="dataLancamento" cssClass="form-control"/>
            <form:errors path="dataLancamento"/>
        </div>
        <c:forEach items="${tipos }" var="tipoPreco" varStatus="status">
            <div class="form-group">
                <label>${tipoPreco }</label>
                <form:input path="precos[${status.index }].valor" cssClass="form-control" />
                <form:hidden path="precos[${status.index }].tipo" value="${tipoPreco }" />
            </div>
        </c:forEach>
        <!-- <div class="form-group"> 
            <label>Sumário</label>
            <input name="sumario" type="file" class="form-control">
        </div>
         --> 
        <button type="submit" class="btn btn-primary">Atualizar</button>
    </form:form>

    </div>

</body>
</html>

Cara, na tua página da lista de produtos chama um método alterar passando o id do produto.

<c:forEach items="${products }" var="product">
                    <tr>
                        <td><a href="${s:mvcUrl('PC#detail').arg(0,product.id).build() }">${product.title }</a></td>
                        <td>${product.description }</td>
                        <td>${product.pages }</td>
                        <td><fmt:formatDate pattern="dd/MM/yyyy" value="${product.published.time }" /></td>
                        <td>${product.prices }</td>
                        <td>
                            <a href="${s:mvcUrl('PC#alterar').arg(0,product.id).build() }">Alterar</a>
                            <a href="<c:url value='products/remove'/>/${product.id}">Remover</a>
                        </td>
                    </tr>
                </c:forEach>

Nesse método alterar tu recebe o produto a ser alterado e carrega um formulário de atualização para o produto (até aí está tudo ok aqui no meu código).

@RequestMapping("/alterar/{id}")
    public ModelAndView alterar(@PathVariable("id") Integer id) {
        System.out.println("Entrando no alterar...");
        ModelAndView modelAndView = new ModelAndView("/products/update");
        Product product = productDAO.find(id);
        modelAndView.addObject("product", product);
        return modelAndView;
    }

Nesse novo formulário para alteração, tu vai pegar e submeter o mesmo produto novamente, só que agora pra uma nova action no teu controller:

@RequestMapping(value = "/update", method=RequestMethod.POST)
    @CacheEvict(value="productsHome", allEntries=true)
    public ModelAndView update(MultipartFile file, @Valid Product product, BindingResult result, RedirectAttributes redirectAttributes) {
        System.out.println(file.getOriginalFilename());
        System.out.println("Id do produto: " + product.getId());

        if (result.hasErrors()) {
            System.out.println(result.getFieldError());
            return form(product);
        }
        String path = fileSaver.write("fileLocation", file);
        product.setFileLocation(path);

        productDAO.update(product);
        redirectAttributes.addFlashAttribute("bookAddedMessage", "Product " + product.getTitle() + " added with success.");
        return new ModelAndView("redirect:/products");
    }

Aí aqui estou com um problema pois o id do produto está nulo. Esse método update do ProductDAO era apenas pra tu dar um merge no produto na base de dados e estava tudo feito, mas com o id chegando ai complica... Assim que eu conseguir resolver isso eu te falo... é que não vou ter tempo agora creio...

Class ProductDAO {

    public void update(Product product) {
        manager.merge(product);
    }

}

Mas já tem uma coisa aí pra você tentar finalizar...