Как создать собственный обработчик 404 страниц с помощью Play 2.0? - PullRequest
27 голосов
/ 03 апреля 2012

Каков предпочтительный способ обработки 404 ошибок в Play 2.0 и отображения хорошего шаблонного представления?

Ответы [ 7 ]

23 голосов
/ 03 апреля 2012

Вы можете переопределить метод onHandlerNotFound для вашего объекта Global, например:

object Global extends GlobalSettings {
  override def onHandlerNotFound(request: RequestHeader): Result = {
    NotFound(views.html.notFound(request))
  }
}
20 голосов
/ 21 августа 2013

Обратите внимание, что на самом деле нужно решить две разные проблемы:

  1. Отображение пользовательской страницы 404, когда "обработчик не найден", например когда пользователь переходит на недопустимый URL-адрес и

  2. Отображение пользовательской страницы 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, чтобы он ссылался на ваш новый "Global" Я положил его в пакет контроллеров, но это не обязательно должно быть:

...
application.global=controllers.Global

Шаг 4: перезапустите и перейдите по неверному URL.

Сценарий "Настоящий обработчик не может найти объект"

Во втором сценарии существующий обработчик хочет показать пользовательский 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"))
    }
  }
}

Что мне нравится в этом, так это чистое разделение кода состояния (200 против 404) и возвращенного HTML-кода (showFruit против noSuchFruit).

НТН Андрей

6 голосов
/ 01 марта 2013

Если вы хотите сделать то же самое, используя 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).

2 голосов
/ 14 сентября 2016

Обратите внимание, что команда разработчиков Play прилагает немало усилий, чтобы отойти от глобального состояния в Play, поэтому с версии 2.4 GlobalSettings и глобальный объект приложения устарели.

HttpErrorHandler.onClientErrorиспользоваться вместо GlobalSettings.onHandlerNotFound.В основном создайте класс, который наследуется от HttpErrorHandler, и предоставьте реализацию для метода onClientError.

Чтобы определить тип ошибки (404 в вашем случае), вам необходимо прочитать код состояния, которыйпередается в качестве одного из аргументов метода, например

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 знать, какой обработчик использовать, вы можете поместить обработчик ошибок в корневой пакет или настроить его в application.conf, используя play.http.errorHandlerключ конфигурации, например,

play.http.errorHandler = "my.library.MyErrorHandler"

Подробнее об обработке ошибок вы можете найти здесь: для Scala или Java .

2 голосов
/ 06 февраля 2014

Это работает в 2.2.1. В Global.java:

public Promise<SimpleResult> onHandlerNotFound(RequestHeader request) {
    return Promise.<SimpleResult>pure(notFound(
        views.html.throw404.render()
    ));
}

Убедитесь, что у вас есть представление под названием /views/throw404.scala.html

0 голосов
/ 18 мая 2017

Для Java, если вы хотите просто перенаправить на главную страницу, я решил это следующим образом.

@Override
public Promise<Result> onHandlerNotFound(RequestHeader request) {
    return Promise.pure(redirect("/"));
}
0 голосов
/ 12 мая 2014

Это работает в 2.2.3 Play - Java

public Promise<SimpleResult> onHandlerNotFound(RequestHeader request) {
    return Promise<SimpleResult>pure(Results.notFound(views.html.notFound404.render()));
}

html должен быть в /views/notFound404.scala.html Не забудьте добавить Results.notFounf () и импортировать play.mvc.Results;

...