1
resposta

Erro no form.jsp

Olá,

Estou com dificuldades no seguinte trecho de codigo, já baixei o arquivo disponibilizado nas aulas porém o erro persiste:

Erro gerado no navegador:

org.apache.jasper.JasperException: An exception occurred processing [/WEB-INF/views/produto/form.jsp] at line [15]

12:         <div class="panel-heading">Novo produto</div>
13: 
14:         <div class="panel-body">
15:             <form action="${spring:mvcUrl('cadastraProduto').build()}" method="post">
16:                 <div class="form-group">
17:                     <label for="nome">
18:                         Nome:

Erro gerado no arquivo produto/form.jsp:

The method getBuild() is undefined for the type MvcUriComponentsBuilder.MethodArgumentBuilder

Segue arquivo JSP:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>


<c:import url="../template/top.jsp" />
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">Novo produto</div>

        <div class="panel-body">
            <form action="${spring:mvcUrl('PC#cadastraProduto').build()}" method="post">
                <div class="form-group">
                    <label for="nome">
                        Nome:
                    </label>
                    <input type="text" class="form-control" name="nome" value="${produto.nome}">
                    <form:errors path="produto.nome" />
                </div>

                <div class="form-group">
                    <label for="nome">
                        Link da foto:
                    </label>
                    <input type="text" class="form-control" name="linkDaFoto" value="${produto.linkDaFoto}">
                    <form:errors path="produto.linkDaFoto" />
                </div>
                <div class="form-group">
                    <label for="nome">
                        Preço:
                    </label>
                    <input type="text" class="form-control" name="preco" value="${produto.preco}">
                    <form:errors path="produto.preco" />
                </div>
                <div class="form-group">
                    <label for="nome">
                        Loja:
                    </label>
                    <select name="loja.id" class="form-control">
                        <option value="selecione">Selecione</option>
                        <c:forEach items="${lojas}" var="loja">
                            <c:choose>
                                <c:when test="${produto.loja.id == loja.id }">
                                    <option value="${loja.id}" selected>${loja.nome}</option>    
                                </c:when>
                                <c:when test="${produto.loja.id != loja.id }">
                                    <option value="${loja.id}">${loja.nome}</option>    
                                </c:when>
                            </c:choose>
                        </c:forEach>
                    </select>
                    <form:errors path="produto.loja.id" />
                </div>
                <div class="form-group">
                    <label for="descricao">
                        Categoria:
                    </label><br>
                    <c:forEach items="${categorias}" var="categoria" varStatus="status">
                        <c:set var="contains" value="false"/>

                        <c:forEach items="${produto.categorias}" var="categoriaProduto" varStatus="statusProduto">
                            <c:if test="${categoriaProduto.id == categoria.id}">
                                <c:set var="contains" value="true"/>        
                            </c:if>
                        </c:forEach>    
                        <c:choose>    
                            <c:when test="${contains}">
                                 <input type="checkbox" name="categorias" value="${categorias[status.index].id}" checked> 
                                    ${categoria.nome}<br>
                                <c:set var="contains" value="false"/>        
                            </c:when>
                            <c:when test="${not contains }">
                                <input type="checkbox" name="categorias" value="${categorias[status.index].id}"> 
                                    ${categoria.nome}<br>
                            </c:when>
                        </c:choose>
                    </c:forEach>
                </div>
                <div class="form-group">
                    <label for="descricao">
                        Descrição:
                    </label>
                    <textarea name="descricao" class="form-control">${produto.descricao}</textarea>
                </div>
                <form:errors path="produto.descricao" />

                <c:if test="${produto.id != null}">
                    <div class="form-group">
                        <input type="submit" class="btn btn-success" value="Atualizar">
                        <input type="hidden" name="id" value="${produto.id}">
                    </div>
                </c:if>

                <c:if test="${produto.id == null}">
                    <div class="form-group">
                        <input type="submit" class="btn btn-success" value="Cadastrar">
                    </div>
                </c:if>

             </form>
        </div>
    </div>
</div>


</body>
</html>

Por fim, o controller responsavel por esta requisição:

@Controller
@RequestMapping("/produto")
public class ProdutoController {

    @Autowired
    private ProdutoDao produtoDao;

    @Transactional
    @RequestMapping(method = RequestMethod.POST, name = "cadastraProduto")
    public String salvar(@ModelAttribute @Valid Produto produto, BindingResult result, RedirectAttributes atts) {

        if (result.hasErrors()) {
            return form(produto);
        }

        produtoDao.insere(produto);

        return "redirect:/";
    }

Qualquer sugestão é bem vinda.

Grato.

1 resposta

Olá Cleverton, tudo bem? Peço desculpas pelo demora no retorno! Bem, por algum motivo que não consegue entender o spring:mvcUrl não consegue fazer o build pelo nome que está configurado no @RequestMapping do controller. Então uma solução, baseada na dica do Thiago nesse outro tópico é:

  • Você pode deixar o mapeamento no ProdutoController como está:
    @RequestMapping(method=RequestMethod.POST, name="cadastraProduto", value="cadastraProduto")
  • Porém no form.jsp, você precisa adicionar um contextPath usando o c:url, isso pode ser feito depois da importação do template top, o código ficando da seguinte forma:
    <c:url value="/" var="contextPath" />
  • E por último não use o mvcUrl e sim uma URL comum usando a variável contextPath no form, da seguinte forma:
    <form action="${contextPath}produto/cadastraProduto" method="post">

Isso deve funcionar corretamente!

Espero ter ajudado e bons estudos!