Debugging the Spring MVC 404 “No mapping found for HTTP request” Error – 调试Spring MVC 404 “没有找到HTTP请求的映射 “错误

最后修改: 2019年 9月 10日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

Spring MVC is a traditional application built using the Front Controller Pattern. DispatcherServlet, which acts as the front controller, is responsible for routing and request processing.

Spring MVC是一个使用前置控制器模式构建的传统应用程序。DispatcherServlet,它作为前台控制器,负责路由和请求处理。

As with any web application or website, Spring MVC returns the HTTP 404 response code when the requested resource can’t be found. In this tutorial, we’ll look at common causes for 404 errors in Spring MVC.

与任何Web应用程序或网站一样,当请求的资源找不到时,Spring MVC会返回HTTP 404响应代码。在本教程中,我们将了解Spring MVC中404错误的常见原因

2. Possible Causes for 404 Response

2.404响应的可能原因

2.1. Wrong URI

2.1.错误的URI

Let’s say we have a GreetingController that is mapped to /greeting and renders greeting.jsp:

假设我们有一个GreetingController,它被映射到/greeting并渲染greeting.jsp

@Controller
public class GreetingController {

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

The corresponding view renders the value of the message variable:

相应的视图渲染了message变量的值。

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

As expected, making a GET request to /greeting works:

正如预期的那样,向/greeting发出GET请求是可行的。

curl http://localhost:8080/greeting

We’ll see an HTML page with the message “Hello World”:

我们将看到一个带有 “Hello World “信息的HTML页面。

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

One of the most common reasons for seeing 404 is using an incorrect URI. For example, it would be wrong to make GET request to /greetings instead of /greeting:

看到404的一个最常见的原因是使用了一个不正确的URI。例如,向/greetings而不是/greeting发出GET请求是错误的。

curl http://localhost:8080/greetings

In such a case, we’d see a warning message in the server logs:

在这种情况下,我们会在服务器日志中看到一个警告信息。

[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'

And the client would see an error page:

而客户会看到一个错误页面。

<html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1>Http Error Code : 404. Resource not found</h1>
    </body>
</html>

To avoid this, we need to make sure that we have entered the URI correctly.

为了避免这种情况,我们需要确保我们正确输入了URI。

2.2. Incorrect Servlet Mapping

2.2.不正确的Servlet映射

As explained earlier, DispatcherServlet is the front controller in Spring MVC. Hence, just as in a standard servlet-based application, we need to create a mapping for the servlet using the web.xml file.

如前所述,DispatcherServlet是Spring MVC的前置控制器。因此,就像在一个标准的基于Servlet的应用程序中一样,我们需要使用web.xml文件为Servlet创建一个映射。

We define the servlet inside the servlet tag and map it to a URI inside the servlet-mapping tag. We need to ensure that the value of url-pattern is correct because it’s quite common to see suggestions where the servlet is mapped to “/*” — note the trailing asterisk:

我们在servlet标签中定义servlet,并在servlet-mapping标签中把它映射到URI。我们需要确保url-pattern的值是正确的,因为很常见的建议是Servlet被映射到”/*”–注意后面的星号

<?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>

Now, if we request /greeting, we’d see a warning in the server logs:

现在,如果我们请求/greeting我们会在服务器日志中看到一个警告。

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'

This time the error states that greeting.jsp is not found, and the user sees a blank page.

这一次,错误指出greeting.jsp没有找到,用户看到的是一个空白页面。

To fix the error, we need to map DispatcherServlet to “/” (without the trailing asterisk) instead:

为了修复错误,我们需要将DispatcherServlet映射到”/”(不含尾部星号),而不是:

<servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

After fixing the mapping, everything should work correctly. Requesting /greeting now shows the message “Hello, World!”:

在修复了映射之后,一切都应该正常工作了。请求/greeting现在显示 “Hello, World!”的信息。

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

The reasoning behind the problem is that if we map DispatcherServlet to /*, then we are telling the application that every single request arriving at our application is to be served by DispatcherServlet. However, that’s not a correct approach because DispatcherServlet is not capable of doing this. Instead, Spring MVC expects an implementation of ViewResolver to serve views such as JSP files.

这个问题背后的原因是,如果我们将DispatcherServlet映射到/*,,那么我们就告诉应用程序,到达我们应用程序的每一个请求都要由DispatcherServlet提供服务。然而,这并不是一个正确的方法,因为DispatcherServlet并不能够做到这一点。相反,Spring MVC期望通过实现ViewResolver来服务视图,如JSP文件。

3. Conclusion

3.总结

In this quick article, we explained how to debug 404 errors in Spring MVC. We went through the two most common reasons for receiving a 404 response from our Spring application. The first was using an incorrect URI while making the request. The second was mapping the DispatcherServlet to the wrong url-pattern in web.xml.

在这篇快速文章中,我们解释了如何在Spring MVC中调试404错误。我们经历了从Spring应用程序中收到404响应的两个最常见的原因。第一个原因是在发出请求时使用了不正确的URI。第二个原因是将DispatcherServlet映射到web.xml中的错误url-pattern

As always, the full implementation of this tutorial can be found over on Github.

一如既往,本教程的完整实现可以在Github上找到over