java - 手动调用PlayFramework自定义错误页面

标签 java scala playframework playframework-2.4

我在 PlayFramework 中实现了自定义页面,就像文档中所述:https://www.playframework.com/documentation/2.4.x/JavaErrorHandling

我在 application.conf 中添加了对 ErrorHandler 的引用

play.http.errorHandler = "com.company.ErrorHandler"

我已经实现了 ErrorHandler 本身:

public class ErrorHandler extends DefaultHttpErrorHandler {

    @Inject
    public ErrorHandler(Configuration configuration, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) {
        super(configuration, environment, sourceMapper, routes);
    }

    @Override
    public F.Promise<Result> onClientError(Http.RequestHeader requestHeader, int errorCode, String message) {
        Logger.debug("Error: onClientError : " + errorCode + ", message: " + message);
        return super.onClientError(requestHeader, errorCode, message);
    }

    @Override
    public F.Promise<Result> onServerError(Http.RequestHeader request, Throwable exception) {
        Logger.debug("Error: onServerError general");
        return F.Promise.pure(redirect(com.company.routes.ErrorController.serverErrorPage()));
    }

    @Override
    protected F.Promise<Result> onBadRequest(Http.RequestHeader request, String message) {
        Logger.debug("Error: onBadRequest, message: " + message);
        return F.Promise.pure(redirect(com.company.routes.ErrorController.badRequestPage()));
    }

    @Override
    protected F.Promise<Result> onForbidden(Http.RequestHeader request, String message) {
        Logger.debug("Error: onForbidden, message: " + message);
        return F.Promise.pure(redirect(com.company.routes.ErrorController.forbiddenPage()));
    }

    @Override
    protected F.Promise<Result> onNotFound(Http.RequestHeader request, String message) {
        Logger.debug("Error: onNotFound, message: " + message);
        return F.Promise.pure(redirect(com.company.routes.ErrorController.notFoundPage()));
    }

    @Override
    protected F.Promise<Result> onOtherClientError(Http.RequestHeader request, int statusCode, String message) {
        Logger.debug("Error: onOtherClientError, message: " + message);
        return F.Promise.pure(redirect(com.company.routes.ErrorController.errorDefaultPage()));
    }
}

当框架本身抛出错误时,自定义页面效果很好。

虽然我在从 Controller 重定向到错误页面时遇到问题。当我调用终点时:

public Result contact() {
    return Results.forbidden("Forbidden");
}

未显示 ErrorHander 的错误页面。我只看到文字“禁止”。

如何在不显式重定向到自定义错误页面的情况下显示该页面?

最佳答案

我遇到了类似的问题,我通过重写 onClientError 并切换到不同的 HTTP 状态代码来解决它:

public class ErrorHandler extends DefaultHttpErrorHandler {

  @Inject
  public ErrorHandler(Configuration configuration, Environment environment,
        OptionalSourceMapper sourceMapper, Provider<Router> routes) {
      super(configuration, environment, sourceMapper, routes);
  }

  @Override
  public Promise<Result> onClientError(RequestHeader request, int statusCode,
        String message) {
    switch (statusCode) {
    case Http.Status.BAD_REQUEST:
        Logger.info(CLASS_NAME + ".onBadRequest: " + message);
        return Promise.<Result> pure(
                Results.badRequest(views.html.error.render("Bad request")));
    case Http.Status.NOT_FOUND:
        Logger.info(CLASS_NAME + ".onNotFound: Requested page \""
                + request.uri() + "\" couldn't be found.");
        return Promise.<Result> pure(
                Results.notFound(views.html.error.render("Requested page \""
                        + request.uri() + "\" couldn't be found.")));
    case Http.Status.FORBIDDEN:
        Logger.info(CLASS_NAME + ".onForbidden: " + message);
        return Promise.<Result> pure(Results
                .forbidden("You're not allowed to access this resource."));
    default:
        Logger.info(CLASS_NAME + ".onClientError: HTTP status code "
                + statusCode + ", " + message);
        return Promise.<Result> pure(Results.status(statusCode,
                views.html.error.render("Internal server error")));
    }
  }

  @Override
  public Promise<Result> onServerError(RequestHeader request,
        Throwable exception) {
    Logger.info(CLASS_NAME + ".onServerError: Internal server error",
            exception);
    return Promise.<Result> pure(Results.internalServerError(
            views.html.error.render("Internal server error")));
  }

}

也许这甚至是 Play 文档中的一个错误?至少在 HttpErrorHandler 接口(interface)中,它不会谈论除 onServerErroronClientError ( https://www.playframework.com/documentation/2.4.0/api/java/play/http/HttpErrorHandler.html ) 之外的其他方法。

关于java - 手动调用PlayFramework自定义错误页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36469364/

相关文章:

java - 无法访问 Play-1.2 View 模板内的 HashMap

process - 这个支付用户的过程是否可靠和安全?

java - 在控制台中手动写入的替代方法

java - 如何从数据集中删除某些列?

scala - Scala 的 “if … else” 可以作为库函数实现吗?

Scala 风格 : for vs foreach, 过滤器、 map 和其他

Java 电子邮件 UTF 验证

java - Selenium - 写入网络驱动器。可以写入文本文件,但不能写入图像文件

scala - Apache spark消息理解

java - hibernate 异常 : Found two representations of same collection