JavaのWebアプリケーション開発フレームワークによる、Webサイト開発の顛末記です。

EclipseのMavenを使った、Spring-MVC、Thymeleaf、MyBatis 等のプログラミングテクニックを、
備忘録的に記録しています。実際に動くソースコードを多用して説明していますので、
これからEclipseや、Spring-MVCを始めたいと思っている人にとって、少しでも参考になれば幸いです。
■Spring Boot の小径 第4歩 Spring Boot 匍匐前進
4-11)エラーページについて
Spring-MVCアプリケーションや、一般的なTomcatで動作するアプリケーションでは、
HTTPエラーや例外が発生した時に表示するページを、
tomcatデプロイメント記述子(web.xml)の 、エラーページ(error-page)要素で定義します。
例)
<error-page>
  <error-code>404</error-code>
  <location>/error.html</location>
</error-page>

この定義を行っておくと、
http://arimodoki.dip.jp/unknown.html と存在しないURLがリクエストされたら、
http://arimodoki.dip.jp/error.html のエラーページにリダイレクトします。

しかしながら、Spring Boot では既にご承知の通り、web.xml自体が存在しません。
ここではSpring Bootで、エラーページを設定する方法をご紹介しておきます。
エラーページの配置
 ネットを検索すると、エラーページの設定方法はいくつかあるようですが、
 
 ・1)一番手っ取り早い方法。静的エラーページerror.htmlの配置
  Spring Boot と、Thymeleaf を組み合わせて使っている場合は、
  classpath(src/main/resources/):/template/ディレクトリ配下に、
  error.html という名前でファイルを配置します。
  これだけで、http://arimodoki.dip.jp/xxxyyyzzzのように存在しないようなURLがリクエストされた場合、
  エラーページ、error.html が表示されます。
   ※)ただし、ブラウザのURLは、http://arimodoki.dip.jp/xxxyyyzzz のまま。

  src/main/resources/template/error.html

  <!DOCTYPE html>
  
  <html xmlns:th="http://www.thymeleaf.org" lang="ja" >
  <head>
  <title>Error</title>
  <meta charset="UTF-8" />
  </head>
  
  <body>
  <table>
    <tr>
      <td>
        <span>Page Not Found!!!</span>
      </td>
    </tr>
  </table>
  </body>
  </html>
  
  
 ・2)次に、カスタムエラーページとエラーページコントローラで制御する方法。
  まず、エラー表示用HTML
  src/main/resources/template/404error.html
  <!DOCTYPE html>
  
  <html xmlns:th="http://www.thymeleaf.org" lang="ja" >
  <head>
  <title>Error</title>
  <meta charset="UTF-8" />
  </head>
  
  <body>
  <table>
    <tr>
      <td>
        <span th:text="${errmessage}">Error</span>
      </td>
    </tr>
  </table>
  </body>
  </html>
  
  
  そして、エラーページコントローラ
  src/main/java/jp/dip/arimodoki/cntl/ErrorCntl.java
  ErrorControllerインターフェースをインプリメントするのがミソの様です。

  package jp.dip.arimodoki.cntl;
  
  import org.springframework.boot.autoconfigure.web.ErrorController;
  import org.springframework.http.HttpStatus;
  import org.springframework.stereotype.Controller;
  import org.springframework.ui.Model;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestMethod;
  import org.springframework.web.bind.annotation.ResponseStatus;

  /**
   * エラーページコントローラ
   * ErrorControllerを継承する
   */
  @Controller
  public class ErrorCntl implements ErrorController {
     /**
     * エラーハンドラ
     * model に errmessageをセットして、VIEW(404.html)を表示します
     * マッピング名は、"/error" でないと動かない
     */
    @RequestMapping(value = "/error")
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String error404(Model model) {
      model.addAttribute("errmessage", "pageNotFound");
      return "404error";
    }
  
     /**
     * getErrorPath()をOverrideするだけ
     * 特に処理は必要ありません
     */
     @Override
     public String getErrorPath() {
       return "";
    }
  }
  
  アプリケーションを起動して、適当に存在しないURLをリクエストしてみましょう。
  エラーハンドラerror404()が起動して、pageNotFoundが表示されれば成功です。

 上の2種類の方法が王道の様で、どこを探してみても大体決まってどちらかの解説しか書いてありません。
 まぁ、確かにこれでもなんとかならないことはありませんが、
 第一の方法は、静的なページなので、固定のメッセージしか表示できないのでNG。
 第二の方法は、エラーのステータスコードによって、メッセージを変えることができるので、
 Goodかと思い早速取り組んでみましたが、ちょっと困った状況が発生してしまいました。
 Spring Boot で、HTTPエラー(404,500等)が発生すると、特別なマッピングURL "/error" が発生するのですが、
 この実験プロジェクトでは、application.properties設定ファイルで、appconfig.url-pattern=*.html を定義しているので
 /error というURLをハンドリングできずに、tomcatのデフォルトHTTPステータスエラーページが表示されてしまいました。
 
 色々と試行錯誤した結果、
 「4-8)環境設定の外部ファイル注入」でご紹介した、
 src/main/java/jp/dip/arimodoki/config/WebConfig.java の
 dispatcherRegistration()メソッドに、一行処理を追加することで、"/error" リクエストを
 マッピングできるようになりました。
 
  @Bean
  public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) {
    ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
    registration.setLoadOnStartup(1);
     //下の一行を追加する
    registration.addUrlMappings("/error");
    registration.addUrlMappings(this.urlpattern);
    return registration;
  }
 
 これで、上のErrorCntl.javaが正常に動作する様になり、
 404,500等のHTTPエラー発生時のページリダイレクトが可能となりました。
 
 
 ・3)最後に、もう一つエラーページ処理を行うエラーハンドラをご紹介しておきます。
  こちらは、コントローラではなく、汎用的なエラーハンドリングクラスを使った方法です。
  viewは、前と同じerror.htmlを使います。
  エラーハンドラクラス
  src/main/java/jp/dip/arimodoki/common/GlobalErrorViewResolver.java
    
  HTTP 404や500エラーが発生すると、このハンドラでキャッチされ、エラーページが表示されます。
  ※)こちらのハンドラと、上のエラーコントローラが両方存在する場合は、
    エラーコントローラ(ErrorCntl)の方が優先されます。