Redirect JSF-Ajax Request in ServletFilter

Servlet Filter sind einfache Möglichkeiten den Zugriff auf die eigene Anwendung ein zu schränken und global Prüfungen auf z.B. Benutzer durch zu führen. In einem Fehlerfall ist das Senden eines Fehlerstatus schnell zu der Hand, der den User darüber informiert das es schief gelaufen ist:

@WebFilter(filterName = "MyFilter", urlPatterns = "/pages/*")
public class HMGLDAPungleichPCFirmaFilter
    implements Filter
{

    @Inject
    private Benutzer benutzer;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException
    {

        // Benutzer prüfungen...
        // Bei Fehler/Ungültige Informationen:
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        httpResponse.sendError(400, "Da stimmt was nicht...");
    }
}

Das klappt wunderbar bis die erste Ajax Anfrage einen solchen Fehler produziert. Zwar wir der Fehlerstatus korrekt an den Browser weiter gegeben, hier müssten wir aber explizit auf einen Ajax Fehler reagieren (z.B. mittels onError-Attribut) und diesen in eine entsprechende Fehlerausgabe umwandeln. Wäre es nicht schöner wenn auch im Falle einer Ajax-Anfrage unsere Fehlermeldung vom Server generriert wird?

Auch das ist möglich. Dazu müssen wir zuerst feststellen ob es sich bei unserer Anfrage um einen Ajax-Request handelt. Hierzu greifen wir auf die Header-Werte des Requests zu und prüfen das Attribut ‚Faces-Request‘ auf den Wert ‚partial/ajax‘. Sollte dies der Fall sein übermittel wir nicht eine Fehler-Response sondern weisen den browserseitigen JavaScript Code an einen erneuten Request auf eine explizite Fehlerseite zu stellen die hier angezeigt wird.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException
{

    // Benutzer prüfungen...
    // Bei Fehler/Ungültige Informationen:
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    HttpServletRequest httpRequest = (HttpServletRequest) request;

    if (isAjaxRequest(httpRequest)) {
        String rediect=redirectForAjax(httpRequest, "error.xhtml");
        PrintWriter writer = response.getWriter();
        writer.write(rediect);
        writer.close();
    }
    else {
        httpResponse.sendError(400, "Da stimmt was nicht...");
    }

}

private String redirectForAjax(HttpServletRequest request, String page)
{
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version='1.0' encoding='UTF-8'?>");
    sb.append("<partial-response><redirect url=\"").append(request.getContextPath()).append(request.getServletPath()).append(page).append("\"/></partial-response>");
    return sb.toString();
}

private boolean isAjaxRequest(HttpServletRequest request)
{
    return "partial/ajax".equals(request.getHeader("Faces-Request"));
}
Advertisements

Über Dominik Mathmann
Dominik Mathmann arbeitet als Berater, Entwickler und Trainer bei der GEDOPLAN GmbH. Auf Basis seiner langjährigen Erfahrung in der Implementierung von Java-EE-Anwendungen leitet er Seminare, hält Vorträge und unterstützt Kunden bei der Konzeption und Realisierung von Webanwendungen vom Backend bis zum Frontend. Sein derzeitiger Schwerpunkt liegt dabei auf der Entwicklung von JSF-Anwendungen. Er sieht die stärker werdende Position von JavaScript-Frameworks jedoch positiv und beschäftigt sich darüber hinaus mit Webframeworks wie AngularJS.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: