play 2.7.xのカスタムエラーページ設定
playのエラーページはデフォルトだとユーザー目線で明らかに気持ち悪いので、カスタムエラーページを設定する方法を調べました。
特に2.7.xは日本語の情報も少ないので、docementを手掛かりに自分で設定することになりました。
※公式のplay-java-ebean-exampleサンプル
定義されてないURLを指定すると、こんなページを吐きます。
だめですね。。。
大まかな手順
①/appにErrorHandler.javaを作成する。
②ErrorHandler.javaで、DefaultHttpErrorHandlerを継承したErrorHandlerクラスを作成し、エラー発生時のメソッドを作成する。
・document該当箇所
www.playframework.com
・メソッド一覧
www.playframework.com
404エラーページの作成
とりあえず、documentを頼りに設置してみる。
・ErrorHandler.java
import com.typesafe.config.Config; import play.*; import play.api.OptionalSourceMapper; import play.api.UsefulException; import play.api.routing.Router; import play.http.DefaultHttpErrorHandler; import play.mvc.Http.*; import play.mvc.*; import javax.inject.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @Singleton public class ErrorHandler extends DefaultHttpErrorHandler { @Inject public ErrorHandler( Config config, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) { super(config, environment, sourceMapper, routes); } protected CompletionStage<Result> onNotFound(RequestHeader request, String message) { return CompletableFuture.completedFuture( Results.notFound("Hey! This Page is not Found!!!!!")); } }
先ほどのURLを調べると、
ちゃんと思った文面が出力されましたね。
404のカスタムエラーページの作成
onNotFoundでカスタムエラーページのオブジェクトを返すように設定します。
今回はpage404.scala.htmlというviewを作成して、Results.notFound()に渡します。
※プロジェクトは、なんでもよいのですが、公式のplay-java-hello-world-tutorialで検証しました。
・ErrorHandler.java
import com.typesafe.config.Config; import play.*; import play.api.OptionalSourceMapper; import play.api.UsefulException; import play.api.routing.Router; import play.http.DefaultHttpErrorHandler; import play.mvc.Http.*; import play.mvc.*; import play.twirl.api.Html; import javax.inject.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @Singleton public class ErrorHandler extends DefaultHttpErrorHandler { @Inject public ErrorHandler( Config config, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) { super(config, environment, sourceMapper, routes); } protected CompletionStage<Result> onNotFound(RequestHeader request, String message) { return CompletableFuture.completedFuture( Results.notFound(views.html.page404.render())); } }
・page404.scala.html
@()
@main("404") {
<h1>This is custom error message!!!</h1>
}
・main.scala.html
@* * This template is called from the `index` template. This template * handles the rendering of the page header and body tags. It takes * two arguments, a `String` for the title of the page and an `Html` * object to insert into the body of the page. *@ @(title: String)(content: Html) <!DOCTYPE html> <html lang="en"> <head> <title>@title</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" media="screen" href='@routes.Assets.versioned("stylesheets/main.css")'> <link rel="stylesheet" media="screen" href='@routes.Assets.versioned("stylesheets/prism.css")'> <link rel="shortcut icon" type="image/png" href='@routes.Assets.versioned("images/favicon.png")'> <script src='@routes.Assets.versioned("javascripts/hello.js")' type="text/javascript"></script> <script src='@routes.Assets.versioned("javascripts/prism.js")' type="text/javascript"></script> </head> <body> <section id="top"> <div class="wrapper"> <img class="resize" src="assets/images/play_icon_reverse.svg" alt="logo" /> <h1>Play Hello World Web Tutorial</h1> </div> </section> @content </body> </html>
適当に存在しないURLにアクセスすると、ちゃんとカスタムエラーページが表示されています。
この調子でエラーページを作りこめば、運用に耐えるカスタムページが作れそうです。
まとめ
ErrorHandler.javaのonNotFound()の返り値として、文字列またはviewオブジェクトを設定すると、カスタムエラーページが設定できました。
ネット上で探してもなかなか情報が出てこず、だいぶ苦戦しましたが、分ってしまえばシンプルで使いやすそうですね。