2016-04-07 10 views
1

ich benutzerdefinierte Seiten in PlayFramework wie Dokumentation implementiert sagt: https://www.playframework.com/documentation/2.4.x/JavaErrorHandlingAnruf manuell PlayFramework benutzerdefinierte Fehlerseite

Ich habe hinzugefügt Bezug auf Fehlerbehandler in application.conf

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

und ich habe Fehler Handler selbst implementiert :

Benutzerdefinierte Seiten funktioniert gut, wenn Fehler durch Framework selbst ausgelöst wird.

Obwohl ich ein Problem mit der Umleitung auf Fehlerseiten vom Controller habe. Wenn ich den Endpunkt anrufe:

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

Die Fehlerseite von ErrorHander wird nicht angezeigt. Ich sehe nur Text "Verboten".

Wie kann ich meine benutzerdefinierte Fehlerseite anzeigen, ohne explizit darauf umzuleiten?

Antwort

0

Ich habe einen Weg gefunden, Client-Fehler direkt anzurufen, indem es in das gewünschte Element injiziert wird. Ich landete mit Lösung nach (Play-Framework-2.5):

public class ErrorHandler extends DefaultHttpErrorHandler { 

    private ErrorController errorController; 

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

     this.errorController = errorController; 
    } 

    @Override 
    public CompletionStage<Result> onServerError(Http.RequestHeader request, Throwable exception) { 
     Logger.debug("Error: onServerError general"); 
     return CompletableFuture.completedFuture(this.errorController.serverErrorPage()); 
    } 

    @Override 
    protected CompletionStage<Result> onBadRequest(Http.RequestHeader request, String message) { 
     Logger.debug("Error: onBadRequest, message: " + message); 
     return CompletableFuture.completedFuture(this.errorController.badRequestPage()); 
    } 

    @Override 
    protected CompletionStage<Result> onForbidden(Http.RequestHeader request, String message) { 
     Logger.debug("Error: onForbidden, message: " + message); 
     return CompletableFuture.completedFuture(this.errorController.forbiddenPage()); 
    } 

    @Override 
    protected CompletionStage<Result> onNotFound(Http.RequestHeader request, String message) { 
     Logger.debug("Error: onNotFound, message: " + message); 
     return CompletableFuture.completedFuture(this.errorController.notFoundPage()); 
    } 

    @Override 
    protected CompletionStage<Result> onOtherClientError(Http.RequestHeader request, int statusCode, String message) { 
     Logger.debug("Error: onOtherClientError, message: " + message); 
     return CompletableFuture.completedFuture(this.errorController.errorDefaultPage()); 
    } 
} 

Dann kann ich es nennen mag:

class SomeElement { 

    private final DefaultHttpErrorHandler errorHandler; 

    @Inject 
    public SomeElement(DefaultHttpErrorHandler errorHandler) { 
     this.errorHandler = errorHandler; 
    } 

    public CompletionStage<Result> onAuthFailure(final Http.Context context, 
               final Optional<String> content) { 
     return this.errorHandler.onClientError(context.request(), Http.Status.FORBIDDEN, "You don't have required permissions."); 
    } 
} 
1

Ich hatte ein ähnliches Problem, und ich löste es mit zwingenden onClientError und wechsle in den verschiedenen HTTP-Statuscodes:

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"))); 
    } 

} 

Vielleicht ein Fehler in Spiele-Dokumentation ist es noch? Zumindest in HttpErrorHandler Schnittstelle spricht nicht über andere Methoden als onServerError oder onClientError (https://www.playframework.com/documentation/2.4.0/api/java/play/http/HttpErrorHandler.html).

+0

, dass ein guter Punkt. Wenn Sie jedoch die zugrunde liegende Implementierung von DefaultHttpErrorHandler überprüfen, werden Sie feststellen, dass Aufrufe in onClientError bereits an andere Methoden wie z. onBadRequest, onForbidden. Mein Problem ist, dass trotz der Rückkehr Ergebnisse. verboten(). Die Anfrage wird nicht vom benutzerdefinierten ErrorHandler abgefangen. –

+0

Sie scheinen richtig zu sein. Vielleicht funktioniert es in Play 2.5 - sie haben sich in DefaultHttpErrorHandler im Vergleich zu 2.4 sehr verändert. – Kris

Verwandte Themen