it-swarm.com.de

Was ist der Unterschied zwischen Weiterleitung und Navigation / Weiterleitung und wann ist was zu verwenden?

Was ist der Unterschied zwischen einer Navigation in JSF?

FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);

und eine Umleitung

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);

und wie soll man entscheiden, wann man was verwendet?

Das Problem bei der Navigation ist, dass sich die Seiten-URL nur ändert, wenn faces-redirect=true wird zur Abfragezeichenfolge der Navigations-URL hinzugefügt. In meinem Fall füge ich jedoch faces-redirect=true löst einen Fehler aus, wenn ich zu einer Nicht-JSF-Seite wie einer einfachen HTML-Seite umleiten möchte.

Und eine andere Option ist, wie von BalusC unter JSF 2.0-Umleitungsfehler vorgeschlagen

32
ad-inf

Erstens ist der Begriff "Weiterleiten" in der Welt der Webentwicklung die Aktion, dem Client eine leere HTTP-Antwort mit nur einem Location -Header mit der neuen URL zu senden, unter der der Client ein brandneues GET senden muss Anfrage. Also im Grunde genommen:

  • Der Client sendet eine HTTP-Anfrage an somepage.xhtml.
  • Der Server sendet eine HTTP-Antwort mit dem Header Location: newpage.xhtml Zurück
  • Der Client sendet eine HTTP-Anfrage an newpage.xhtml (Dies wird in der Adressleiste des Browsers angezeigt!)
  • Der Server sendet eine HTTP-Antwort mit dem Inhalt newpage.xhtml Zurück.

Sie können es mit dem im Webbrowser integrierten/hinzugefügten Entwickler-Toolset verfolgen. Drücken Sie F12 in Chrome/IE9/Firebug und überprüfen Sie den Abschnitt "Netzwerk", um es zu sehen.

Der JSF-Navigationshandler sendet keine Umleitung. Stattdessen wird der Inhalt der Zielseite als HTTP-Antwort verwendet.

  • Der Client sendet eine HTTP-Anfrage an somepage.xhtml.
  • Der Server sendet eine HTTP-Antwort mit dem Inhalt newpage.xhtml Zurück.

Da die ursprüngliche HTTP-Anforderung jedoch somepage.xhtml Lautete, bleibt die URL in der Adressleiste des Browsers unverändert. Wenn Sie mit der grundlegenden Servlet-API vertraut sind, sollten Sie verstehen, dass dies den gleichen Effekt hat wie RequestDispatcher#forward() .


Ob das Herausziehen von HttpServletResponse unter den JSF-Hauben und das Aufrufen von sendRedirect() die richtige Verwendung ist; Nein, das ist nicht die richtige Verwendung. Ihre Server-Protokolle werden mit IllegalStateExceptions überfüllt, da Sie JSF auf diese Weise nicht mitteilen, dass Sie bereits die Steuerung der Antwortverarbeitung übernommen haben und JSF daher seine Standard-Antwortverarbeitung nicht ausführen sollte. Sie sollten tatsächlich danach FacesContext#responseComplete() ausführen.

Außerdem sollten Sie jedes Mal, wenn Sie etwas aus dem Paket javax.servlet.* In ein JSF-Artefakt wie eine verwaltete Bean importieren müssen, aufhören, Code zu schreiben, und sich überlegen, ob Sie die Dinge wirklich richtig machen, und sich fragen, ob Sie es tun ist nicht schon ein "Standard-JSF-Weg" für alles, was Sie erreichen wollen und/oder ob die Aufgabe wirklich in eine JSF-verwaltete Bean gehört (es gibt nämlich einige Fälle, in denen ein einfaches Servlet-Filter wäre war ein besserer Ort).

Die richtige Methode zum Ausführen einer Umleitung in JSF ist die Verwendung der Abfragezeichenfolge faces-redirect=true Im Aktionsergebnis:

public String submit() {
    // ...
    return "/newpage.xhtml?faces-redirect=true";
}

Oder verwenden Sie ExternalContext#redirect() , wenn Sie sich nicht in einer Aktionsmethode wie einer Ajax- oder Prerender-Listener-Methode befinden:

public void listener() throws IOException {
    // ...
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}

(Ja, Sie müssen kein try-catch um IOException setzen. Lassen Sie die Ausnahme einfach throws durchlaufen, den Servletcontainer werde damit umgehen)

Oder verwenden Sie NavigationHandler#handleNavigation() in bestimmten Fällen, wenn Sie XML-Navigationsfälle und/oder einen benutzerdefinierten Navigationshandler mit einem eingebauten Listener verwenden:

public void listener() {
    // ...
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}

Warum der Navigationshandler bei "Nur-HTML" -Dateien fehlschlägt, liegt einfach daran, dass der Navigationshandler nur JSF-Ansichten verarbeiten kann, keine anderen Dateien. Sie sollten dann ExternalContext#redirect() verwenden.

Siehe auch:

79
BalusC