Play 2.0で404エラーを処理し、素敵なテンプレートビューを表示するための好ましい方法は何ですか?
onHandlerNotFound
オブジェクトのGlobal
メソッドをオーバーライドできます。例:
object Global extends GlobalSettings {
override def onHandlerNotFound(request: RequestHeader): Result = {
NotFound(views.html.notFound(request))
}
}
解決すべき2つの異なる問題があることに注意してください。
「ハンドラーが見つかりません」の場合にカスタム404ページを表示します。例:ユーザーが無効なURLにアクセスしたとき、および
既存のハンドラーの有効な結果としてカスタム404(NotFound)ページを表示します。
OPは#2を参照していたと思いますが、回答は#1を参照しています。
最初のシナリオでは、「ハンドラーが見つかりません」(つまり、無効なURL)の場合、他の回答は正しいですが、 Play 2.1ドキュメント のように詳細に説明します。
手順1:カスタムグローバルオブジェクトを追加します。
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
object Global extends GlobalSettings {
override def onHandlerNotFound(request: RequestHeader): Result = {
NotFound(
views.html.notFoundPage(request.path)
)
}
}
ステップ2:テンプレートを追加します。これが私のものです:
@(path: String)
<html>
<body>
<h1>Uh-oh. That wasn't found.</h1>
<p>@path</p>
</body>
</html>
ステップ3:conf/application.confを微調整して、新しい「グローバル」を参照します。私はそれをコントローラーパッケージに入れましたが、そうである必要はありません:
...
application.global=controllers.Global
ステップ4:再起動して無効なURLに移動します。
2番目のシナリオでは、既存のハンドラーがカスタム404を表示したいと考えています。たとえば、ユーザーがオブジェクト「1234」を要求しましたが、そのようなオブジェクトは存在しません。良いニュースは、これを行うのは一見簡単だということです。
Ok()の代わりに、応答をNotFound()で囲みます
例えば:
object FruitController extends Controller {
def showFruit(uuidString: String) = Action {
Fruits.find(uuidString) match {
case Some(fruit) => Ok(views.html.showFruit(fruit))
// NOTE THE USE OF "NotFound" BELOW!
case None => NotFound(views.html.noSuchFruit(s"No such fruit: $uuidString"))
}
}
}
これについて私が気に入っているのは、返されたHTML(showFruitとnoSuchFruit)からステータスコード(200と404)が明確に分離されていることです。
HTHアンドリュー
Javaの代わりにScalaを使用して同じことをしたい場合は、次のように行うことができます(これはPlay Framework 2.0.3で機能します):
Global.Java:
import play.GlobalSettings;
import play.mvc.Result;
import play.mvc.Results;
import play.mvc.Http.RequestHeader;
public class Global extends GlobalSettings {
@Override
public Result onHandlerNotFound(RequestHeader request) {
return Results.notFound(views.html.error404.render());
}
}
404エラーテンプレートがviews.html.error404(つまり、views/error404.scala.html)であると仮定します。
Play開発チームはPlayのグローバル状態から脱却するために多大な努力を払っているため、バージョン2.4以降、GlobalSettings
とアプリケーションGlobalオブジェクトは非推奨になっていることに注意してください。
HttpErrorHandler.onClientError
の代わりにGlobalSettings.onHandlerNotFound
を使用する必要があります。基本的に、HttpErrorHandler
から継承するクラスを作成し、onClientError
メソッドの実装を提供します。
エラーのタイプ(あなたの場合は404)を見つけるには、ステータスコードを読み取る必要があります。ステータスコードは、メソッド引数の1つとして渡されます。
if(statusCode == play.mvc.Http.Status.NOT_FOUND) {
// your code to handle 'page not found' situation
// e.g. return custom implementation of 404 page
}
使用するハンドラーをPlayに通知するには、エラーハンドラーをルートパッケージに配置するか、play.http.errorHandler
構成キーを使用してapplication.confで構成します。
play.http.errorHandler = "my.library.MyErrorHandler"
これは2.2.1で機能します。 Global.Javaの場合:
public Promise<SimpleResult> onHandlerNotFound(RequestHeader request) {
return Promise.<SimpleResult>pure(notFound(
views.html.throw404.render()
));
}
/views/throw404.scala.html
というビューがあることを確認してください
Javaの場合、メインページにリダイレクトするだけの場合は、これで解決しました。
@Override
public Promise<Result> onHandlerNotFound(RequestHeader request) {
return Promise.pure(redirect("/"));
}