Depurando o Erro Spring MVC 404 “Nenhum mapeamento encontrado para solicitação HTTP”

Depurando o Erro Spring MVC 404 “Nenhum mapeamento encontrado para solicitação HTTP”

1. Introdução

O Spring MVC é um aplicativo tradicional criado usando o Front Controller Pattern. _https://www..com/spring-dispatcherservlet [DispatcherServlet], _ que atua como o controlador frontal, é responsável pelo roteamento e processamento de solicitações.

Como em qualquer aplicativo ou site da Web, o Spring MVC retorna o código de resposta HTTP 404 quando o recurso solicitado não pode ser encontrado. Neste tutorial, veremos causas comuns de erros 404 no Spring MVC .

2. Possíveis causas para a resposta 404

2.1. URI errado

Digamos que temos um GreetingController que é mapeado para /greeting e renderiza greeting.jsp:

@Controller
public class GreetingController {

    @RequestMapping(value = "/greeting", method = RequestMethod.GET)
    public String get(ModelMap model) {
        model.addAttribute("message", "Hello, World!");
        return "greeting";
    }
}

A visualização correspondente renderiza o valor da variável message:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Greeting</title>
    </head>
    <body>
        <h2>${message}</h2>
    </body>
</html>

Como esperado, fazer uma solicitação GET para /greeting funciona:

curl http://localhost:8080/greeting

Veremos uma página HTML com a mensagem "Hello World":

<html>
    <head>
        <title>Greeting</title>
    </head>
    <body>
        <h2>Hello, World!</h2>
    </body>
</html>

Um dos motivos mais comuns para ver 404 é usar um URI incorreto. Por exemplo, seria errado fazer uma solicitação GET para /greetings em vez de /greeting:

curl http://localhost:8080/greetings

Nesse caso, veríamos uma mensagem de aviso nos logs do servidor:

[http-nio-8080-exec-6] WARN  o.s.web.servlet.PageNotFound -
  No mapping found for HTTP request with URI [/greetings] in DispatcherServlet with name 'mvc'

E o cliente veria uma página de erro:

<html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1>Http Error Code : 404. Resource not found</h1>
    </body>
</html>
*Para evitar isso, precisamos garantir que inserimos o URI corretamente.*

2.2. Mapeamento de servlet incorreto

Como explicado anteriormente, DispatcherServlet é o controlador frontal no Spring MVC. Portanto, assim como em um aplicativo baseado em servlet padrão, precisamos criar um mapeamento para o servlet usando o arquivo web.xml.

Definimos o servlet dentro da tag servlet e o mapeamos para um URI dentro da tag servlet-mapping. Precisamos garantir que o valor de url-pattern esteja correto, porque é bastante comum ver sugestões onde o servlet está mapeado para "/ " - observe o asterisco à direita *:

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
    <!-- Additional config omitted -->
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <!-- Additional config omitted -->
</web-app>

Agora, se solicitarmos /greeting , veremos um aviso nos logs do servidor:

curl http://localhost:8080/greeting
WARN  o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI
  [/WEB-INF/view/greeting.jsp] in DispatcherServlet with name 'mvc'

Dessa vez, o erro informa que greeting.jsp não foi encontrado e o usuário vê uma página em branco.

*Para corrigir o erro, precisamos mapear __DispatcherServlet __ para "/" (sem o asterisco à direita):
<servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Depois de corrigir o mapeamento, tudo deve funcionar corretamente. Solicitar /greeting agora mostra a mensagem "Olá, mundo!":

curl http://localhost:8080/greeting
<html>
    <head>
        <title>Greeting</title>
    </head>
    <body>
        <h2>Hello, World!</h2>
    </body>
</html>

O raciocínio por trás do problema é que, se mapearmos DispatcherServlet para/* *, *, informaremos ao aplicativo que todas as solicitações que chegam ao nosso aplicativo devem ser atendidas por DispatcherServlet. No entanto, essa não é uma abordagem correta, porque DispatcherServlet não é capaz de fazer isso. Em vez disso, o Spring MVC espera que uma implementação de ViewResolver sirva exibições como arquivos JSP.

3. Conclusão

Neste artigo rápido, explicamos como depurar erros 404 no Spring MVC. Analisamos os dois motivos mais comuns para receber uma resposta 404 do nosso aplicativo Spring. O primeiro estava usando um URI incorreto ao fazer a solicitação. O segundo foi mapear o DispatcherServlet para o url-pattern errado em web.xml.

Como sempre, a implementação completa deste tutorial pode ser encontrada over no Github.