Как создать настраиваемый обработчик страницы 404 с Play 2.0?

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

Ответ 1

Вы можете переопределить метод 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.

"Нет обработчика найден" Сценарий

В первом сценарии для "no handler found" (т.е. недопустимый URL) другие ответы имеют это право, но более подробно, на Документацию по версии 2.1 as:

Шаг 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.

"Реальный обработчик не может найти объект" Сценарий

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

НТН Андрей

Ответ 3

Если вы хотите сделать то же самое с помощью 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 - view.html.error404 (т.е. views/error404.scala.html).

Ответ 4

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

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

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

Ответ 5

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

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.

Ответ 6

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

@Override
public Promise<Result> onHandlerNotFound(RequestHeader request) {
    return Promise.pure(redirect("/"));
}

Ответ 7

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

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

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