5
respostas

Exception ao utilizar s:mvcUrl

Boa tarde,

Estou tentando linkar a página de produtos a página de detalhe, mas ao adicionar o s:mvcUrl gera a seguinte exceção:

javax.el.ELException: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [@org.springframework.web.bind.annotation.PathVariable java.lang.Integer] to type [java.lang.String]

ProdutosController

@RequestMapping(method = RequestMethod.GET)
public ModelAndView listar() {
    List<Produto> produtos = new ArrayList<Produto>();
    produtos = produtoDAO.listar();
    ModelAndView modelAndView = new ModelAndView("produtos/lista");
    modelAndView.addObject("produtos", produtos);

    return modelAndView;        
}

@RequestMapping("/detalhe/{id}")
public ModelAndView detalhe(@PathVariable("id") Integer id){
    ModelAndView modelAndView = new ModelAndView("/produtos/detalhe");
    Produto produto = produtoDAO.find(id);
    modelAndView.addObject("produto", produto);
    return modelAndView;
}

lista.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" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Produtos -> Form</title>
</head>
<body>

    <h1>Lista de Produtos</h1>

    <c:if test="${mensagem != null}">
        <h4>${mensagem}</h4>
    </c:if>

    <table>
        <tr>
            <th>Título</th>
            <th>Descrição</th>
            <th>Páginas</th>
            <th>Ações</th>
        </tr>
        <c:forEach items="${produtos}" var="produto" varStatus="status">
            <tr>
                <td>${produto.titulo}</td>
                <td>${produto.descricao}</td>
                <td>${produto.paginas}</td>
                <td><a href="${s:mvcUrl('PC#detalhe').arg(0, produto.id).build()}">Visualizar</a></td>
            </tr>
        </c:forEach>

    </table>
</body>
</html>

Produto

package br.com.ajvideira.casadocodigo.model;

import java.util.Calendar;
import java.util.List;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="produto")
public class Produto {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;

    @Column(name="titulo")
    private String titulo;

    @Column(name="descricao")
    private String descricao;

    @Column(name="paginas")
    private Integer paginas;

    @Temporal(TemporalType.DATE)
    @Column(name="data_lancamento")
    private Calendar dataLancamento;

    @ElementCollection
    @CollectionTable(name="produto_precos", joinColumns = {@JoinColumn(name = "produto_id", referencedColumnName = "id")})
    private List<Preco> precos; 

    private String sumarioPath;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public Integer getPaginas() {
        return paginas;
    }

    public void setPaginas(Integer paginas) {
        this.paginas = paginas;
    }

    public List<Preco> getPrecos() {
        return precos;
    }

    public void setPrecos(List<Preco> precos) {
        this.precos = precos;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public String getSumarioPath() {
        return sumarioPath;
    }

    public void setSumarioPath(String sumarioPath) {
        this.sumarioPath = sumarioPath;
    }

    @Override
    public String toString() {
        return "Produto [id=" + id + ", titulo=" + titulo + ", descricao=" + descricao + ", paginas=" + paginas
                + ", dataLancamento=" + dataLancamento + ", precos=" + precos + ", sumarioPath=" + sumarioPath + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dataLancamento == null) ? 0 : dataLancamento.hashCode());
        result = prime * result + ((descricao == null) ? 0 : descricao.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((paginas == null) ? 0 : paginas.hashCode());
        result = prime * result + ((precos == null) ? 0 : precos.hashCode());
        result = prime * result + ((sumarioPath == null) ? 0 : sumarioPath.hashCode());
        result = prime * result + ((titulo == null) ? 0 : titulo.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Produto other = (Produto) obj;
        if (dataLancamento == null) {
            if (other.dataLancamento != null)
                return false;
        } else if (!dataLancamento.equals(other.dataLancamento))
            return false;
        if (descricao == null) {
            if (other.descricao != null)
                return false;
        } else if (!descricao.equals(other.descricao))
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (paginas == null) {
            if (other.paginas != null)
                return false;
        } else if (!paginas.equals(other.paginas))
            return false;
        if (precos == null) {
            if (other.precos != null)
                return false;
        } else if (!precos.equals(other.precos))
            return false;
        if (sumarioPath == null) {
            if (other.sumarioPath != null)
                return false;
        } else if (!sumarioPath.equals(other.sumarioPath))
            return false;
        if (titulo == null) {
            if (other.titulo != null)
                return false;
        } else if (!titulo.equals(other.titulo))
            return false;
        return true;
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.com.ajvideira.casadocodigo</groupId>
    <artifactId>casadocodigo</artifactId>
    <version>1.0.5-SNAPSHOT</version>
    <packaging>war</packaging>
    <build>
        <finalName>Casa do Codigo</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>jstl-impl</artifactId>
            <version>1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.6.1</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.6.1</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.6.1</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.4.Final</version>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1208</version>
        </dependency>

    </dependencies>
</project>

Desde já agradeço

5 respostas

Oi Jonathan,

Vou ser sincero, não vi o problema. Tem como vc disponibilizar o código no github para eu dar uma olhada?

Alberto,

Segue o link para o github: https://github.com/ajvideira/alura-springmvc

O problema parece ser mesmo no s:mvcUrl, pois se altero para:

<td><a href='<c:url value="produtos/detalhe/${produto.id}" />'>Visualizar</a></td>

não ocorre nenhum erro.

Eu já não gostava dessa forma de chamada (mvcUrl) por usar as iniciais, o que causaria erro se eu tivesse um controller ProdutoController e PostoController. Somado a esse erro do tópico, acho que abandonei de vez essa abordagem.

Conseguiu solucionar?

Amigos, mesmo problema por aqui...