6
respostas

Mapeamento da URL no controller

Olá a todos, tudo certo?
Estou no primeiro curso de Spring MVC na atividade 2, onde preparamos o controller de produtos, bem como as páginas JSP.
A minha classe ProdutosController está funcionando corretamente, no entanto tive que mudar o mapeamento da url na anotação @RequestMapping, pois quando tentava mapear o método formulario na URL /produtos/form, o tomcat dava um erro de 404. Desta forma, tive que mudar o mapeamento para uma outra URL para funcionar corretamente.
Segue minha implementação:

```
package br.com.casadocodigo.loja.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import br.com.casadocodigo.loja.modelo.Produto;

@Controller

public class ProdutosController {

    @RequestMapping("/formproduto")
    public String formulario() {
        System.out.println("Entrando no formulário");
        return "produtos/form";
    }

    @RequestMapping("/produtos")
    public String grava(Produto produto) {
        System.out.println(produto);
        return "produtos/ok";
    }

}

```
A minha dúvida é:
Por que quando tentei mapear a URL do método formulario para /produtos/form deu o erro 404?
Aguardo o retorno.
Abraços!
6 respostas

Oi Guido. Deixa como:

@RequestMapping("/produto/form")

Dá um Clean no projeto pelo eclipse e no Tomcat. Roda o Tomcat e acesse o endereço com

localhost:8080/nome do projeto/produto/form

Obs. Evita pular linha entra a anotação e o que deve anotar:

@Controller
public class ProdutosController{

}
Oi Guilherme, tudo certo?
Mesmo dando um clean no eclipse e no tomcat a url /produto/form não funciona, mas se eu deixar uma URL com uma única barra aí funciona, ex: /produto, ou /form, ou /produtoform.
Minha dúvida aqui no fórum, é por que isso acontece no spring MVC?
Por que ele não deixa mapear uma URL com barra dupla, tal como /produtos/form ou qualquer coisa do tipo?
E ainda corrigi a linha em branco da anotação @Controller.
Aguardo retorno.
Abraços!
Ah, esqueci de dizer que, quando coloco uma URL dupla como /produto/form, o método do controller chega a ser executado, pois todos os sysouts são executados, e as mensagens são mostradas no console.
Só no navegador é que acontece o erro 404.
Abraços!

Então chega a entrar no método e executa o sysout? Então o problema não é no mapeamento, e sim no retorno. O spring não está achando o que está retornando. Coloca uma pagina e tenta retornar

Olá a todos, tudo bem?
Peço desculpas pela demora em dar o retorno a respeito da sugestão acima, foi o natal! rsrsrs
Descobri o que havia de errado no mapeamento da url /produtos/form.
Como já mencionado anteriormente, com esse tipo de mapeamento o método chega a executar os sysouts, mas não retornava a view e dava o erro 404.
Segundo o que foi explicado, o problema não estava no mapeamento, e sim no retorno da view. 
Prestando mais a atenção, percebi na mensagem de erro que, quando mapeio o método do formulário na classe ProdutosController para /produtos/form, o tomcat procura pelo recurso de view na seguinte URL:
localhost:8080/casadocodigo/produtos/WEB-INF/views/produtos/form.jsp, ou seja, ele coloca uma pasta produtos dentro da pasta casadocodigo na URL, por isso dava o erro 404.
O prefixo /WEB-INF/views está setado como prefixo na minha classe AppWebConfiguration, como feito no curso pelo bean InternalResourceViewResolver.
E o sufixo é .jsp.
Como faço para mapear a url /produtos/form no formulário e fazer o tomcat procurar no endereço correto o formulário?
Abraços e um feliz ano novo a todos.
Oi pessoal, tudo certo?
Só para lembrar que ainda estou com aquela dúvida de como fazer para mapear aquela url composta tal como /produtos/form. Quando mapeio deste jeito, o spring não consegue retornar o recurso de view jsp que está dentro da pasta WEB-INF/views/produtos/form.jsp. Vou postar aqui meus arquivos de configuração do spring, bem como o ProdutosController. 
Vocês podem notar que tive que mapear o ProdutosController de forma diferente da que estava no curso. Mas gostaria de auxílio para poder mapear como está no curso.
Abraços.
Segue implementação:

Esse é o ServletSpringMvc
package br.com.casadocodigo.loja.conf;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletSpringMvc extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { AppWebConfiguration.class, JpaConfiguration.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter("UTF-8");
        return new Filter[] { encodingFilter };
    }

}
Agora, segue o AppWebConfiguration
package br.com.casadocodigo.loja.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import br.com.casadocodigo.loja.controllers.HomeController;
import br.com.casadocodigo.loja.dao.ProdutoDao;

@EnableWebMvc
@ComponentScan(basePackageClasses = { HomeController.class, ProdutoDao.class })

public class AppWebConfiguration {

    @Bean
    public InternalResourceViewResolver getResolver() {
        return new InternalResourceViewResolver("WEB-INF/views/", ".jsp");
    }

}
Agora, segue o ProdutosController
package br.com.casadocodigo.loja.controllers;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import br.com.casadocodigo.loja.dao.ProdutoDao;
import br.com.casadocodigo.loja.modelo.Produto;
import br.com.casadocodigo.loja.modelo.TipoPreco;

@Controller
public class ProdutosController {

    @Autowired
    private ProdutoDao dao;

    @RequestMapping("/form")
    public ModelAndView form() {
        System.out.println("Entrando no formulário de cadastro de livros");
        ModelAndView modelAndView = new ModelAndView("produtos/form");
        modelAndView.addObject("tipos", TipoPreco.values());
        return modelAndView;
    }

    @RequestMapping(value = "/produtos", method = RequestMethod.POST)
    public String grava(Produto produto) {
        System.out.println(produto);
        dao.gravar(produto);
        return "produtos/ok";
    }

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

}