[RESOLVIDO] Como corrigir esse e outros erros: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'list'?

Estou implementando um exemplo de um livro sobre Spring Boot, mas, depois de executar, ao tentar acessar a rota /clientes/list ou, então, /clientes/view no navegador aparecem os seguintes erros:

Failed to convert value of type ‘java.lang.String’ to required type
’com.greendog.modelos.Cliente’; nested exception is
org.springframework.core.convert.ConversionFailedException: Failed to
convert from type [java.lang.String] to type [java.lang.Long] for
value ‘list’; nested exception is java.lang.NumberFormatException: For
input string: “list”

inserir a descrição da imagem aqui

Não sei como resolver. Alguém pode me ajudar? Desde já, muito obrigada!

Seguem meu códigos:

Classe Cliente.java:

package com.greendog.modelos;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.validator.constraints.Length;

import com.greendog.modelos.Pedido;

@Entity
public class Cliente {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	
	@NotNull
	@Length(min=2, max=30, message="O tamanho do nome deve ser entre {min} e {max} caracteres.")
	private String nome;
	
	@NotNull
	@Length(min=2, max=300, message="O tamanho do endereçomdeve ser entre {min} e {max} caracteres.")
	private String endereco;
	
	@OneToMany(mappedBy = "cliente", fetch = FetchType.EAGER)
	@Cascade(CascadeType.ALL)
	private List<Pedido> pedidos;
	
	
	public Cliente(Long id, String nome, String endereco) {
		this.id = id;
		this.nome = nome;
		this.endereco = endereco;
	}

	public void novoPedido(Pedido pedido) {
		if(this.pedidos == null) pedidos = new ArrayList<Pedido>();
		pedidos.add(pedido);
		
	}
     /*Getter e Setter */
}

Interface ClienteRepository.java:

package com.greendog.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.greendog.modelos.Cliente;

@Repository
public interface ClienteRepository extends JpaRepository<Cliente, Long>{

}

Classe ClienteController.java:

package com.greendog.controladores;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.greendog.modelos.Cliente;
import com.greendog.repositories.ClienteRepository;

@Controller
@RequestMapping("/clientes")
public class ClienteController {
	
	@Autowired
	private final ClienteRepository clienteRepository = null;
	
	//Exibe as lista de Clientes
	@GetMapping("/")
	public ModelAndView list() {
		Iterable<Cliente> clientes = this.clienteRepository.findAll();
		return new ModelAndView("clientes/list", "clientes", clientes);
	}
	
	//Exibe o detalhe de cada cliente
	@GetMapping("{id}")
	public ModelAndView view(@PathVariable("id") Cliente cliente) {
		return new ModelAndView("clientes/view", "cliente", cliente);
	}
	
	//Direciona para criar novo cliente
	@GetMapping("/novo")
	public String createForm(@ModelAttribute Cliente cliente) {
		return "clientes/form";
	}
	
	//Insere novo cliente através de um formulario
	@PostMapping(params = "form")
	public ModelAndView create(@Valid Cliente cliente, BindingResult result, RedirectAttributes redirect) {
		if(result.hasErrors()){
			return new ModelAndView("clientes/" + "form", "formErros", result.getAllErrors());
		}
		
		cliente = this.clienteRepository.save(cliente);
		redirect.addFlashAttribute("globalMessage", "Cliente gravado com sucesso!");
		
		return new ModelAndView("redirect:/" + "clientes/" + "{cliente.id}", "cliente.id", cliente.getId());
	}
	
	//Atualizar cliente
	@GetMapping(value = "alterar/id")
	public ModelAndView alterarForm(@PathVariable("id") Cliente cliente) {
		return new ModelAndView("cliente/form", "cliente", cliente);
	}
	
	//Remover Cliente
	public ModelAndView remover(@PathVariable("id") Long id, RedirectAttributes redirect) {
		this.clienteRepository.deleteById(id);
		Iterable<Cliente> clientes = this.clienteRepository.findAll();
		ModelAndView mv = new ModelAndView("clientes/list","clientes", clientes);
		mv.addObject("globalMessage", "Cliente removido com sucesso!");
		return mv;
	}
}

Minha estrutura de pastas desse projeto:

inserir a descrição da imagem aqui

Código completo no GitHub.

Vamos pensar um pouco. Você consegue, facilmente, transformar a String “123” em um número inteiro, 123. Também faz o mesmo com a String “234.5” para o número flutuante 234.5.
Agora, como você faria para converter a String “list” em um número?
É o que a exceção apresenta. Você só consegue transformar em valor numérico, aquilo que é numérico.
Ok, mas o que isso significa? Significa que em alguma parte do teu código você espera algo como um número e envia uma String exatamente igual a “list” (o mesmo pra view).

O que acontece e por que?
Quando você invoca uma URL, o servidor não sabe se o que você chama é um site, um sistema ou uma API REST (como é o caso), tampouco se cada / tem um significado específico ou não. A única coisa que o servidor sabe é que você invoca algo com um protocolo específico (http, ftp, etc) e isso é feito através de uma String (http://localhost:8080/clientes/list).

Aqui tem uma possível solução para o problema.
Outra possibilidade

1 curtida

@darlan_machado, perdão? :sweat_smile: Já foi resolvido. Apenas esqueci de marcar como resolvido. Mesmo assim muito obrigada!