1. 序章

Spring MVCは、フロントコントローラーパターンを使用して構築された従来のアプリケーションです。 フロントコントローラーとして機能するDispatcherServlet、は、ルーティングと要求処理を担当します。

他のWebアプリケーションやWebサイトと同様に、Spring MVCは、要求されたリソースが見つからない場合にHTTP404応答コードを返します。 このチュートリアルでは、SpringMVCでの404エラーの一般的な原因を見ていきます。

2. 404応答の考えられる原因

2.1. 間違ったURI

/greetingにマップされgreeting.jspをレンダリングするGreetingControllerがあるとします。

@Controller
public class GreetingController {

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

対応するビューは、message変数の値をレンダリングします。

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

予想どおり、/greetingに対してGETリクエストを行うと機能します。

curl http://localhost:8080/greeting

「HelloWorld」というメッセージを含むHTMLページが表示されます。

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

404が表示される最も一般的な理由の1つは、誤ったURIを使用していることです。 たとえば、GETリクエストを/greetingではなく/greetingsに送信するのは誤りです。

curl http://localhost:8080/greetings

このような場合、サーバーログに警告メッセージが表示されます。

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

そして、クライアントにはエラーページが表示されます。

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

これを回避するには、URIが正しく入力されていることを確認する必要があります。

2.2. サーブレットマッピングが正しくありません

前に説明したように、DispatcherServletはSpringMVCのフロントコントローラーです。 したがって、標準のサーブレットベースのアプリケーションと同様に、web.xmlファイルを使用してサーブレットのマッピングを作成する必要があります。

サーブレットタグ内でサーブレットを定義し、サーブレットマッピングタグ内のURIにマップします。 url-pattern の値が正しいことを確認する必要があります。これは、サーブレットが「/*」にマップされている提案がよく見られるためです。末尾のアスタリスクに注意してください。

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

ここで、 / 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'

今回のエラーは、greeting.jsp が見つからず、ユーザーに空白のページが表示されることを示しています。

エラーを修正するには、代わりに DispatcherServlet を「/」(末尾のアスタリスクなし)にマップする必要があります。

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

マッピングを修正すると、すべてが正しく機能するはずです。 / greeting をリクエストすると、「Hello、World!」というメッセージが表示されるようになりました。

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

この問題の背後にある理由は、DispatcherServletを/*にマップすると、アプリケーションに到着するすべてのリクエストがDispatcherServletによって処理されることをアプリケーションに通知しているためです。 。 ただし、 DispatcherServlet はこれを実行できないため、これは正しいアプローチではありません。 代わりに、Spring MVCは、ViewResolverの実装がJSPファイルなどのビューを提供することを期待しています。

3. 結論

このクイック記事では、SpringMVCで404エラーをデバッグする方法について説明しました。 Springアプリケーションから404応答を受信する最も一般的な2つの理由を確認しました。 1つ目は、リクエストの実行中に誤ったURIを使用したことです。 2つ目は、DispatcherServletweb.xmlの間違ったurl-patternにマッピングすることでした。

いつものように、このチュートリアルの完全な実装は、Githubにあります。