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

Was ist der Unterschied zwischen einer Navigation in JSF?

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

und eine Weiterleitung

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

und wie zu entscheiden, wann was zu verwenden ist?

Das Problem mit der Navigation besteht darin, dass sich die Seiten-URL nicht ändert, es sei denn faces-redirect=true wird zur Abfragezeichenfolge der Navigations-URL hinzugefügt. In meinem Fall triggers das Anfügen von faces-redirect=true Fehler aus, wenn ich auf eine Nicht-JSF-Seite wie eine einfache HTML-Seite redirect möchte.

Und eine weitere Option ist, wie BalusC bei JSF 2.0 Redirect Error vorgeschlagen

Zunächst einmal ist der Begriff “Redirect” in der Web-Entwicklungswelt die Aktion, dem Client eine leere HTTP-Antwort mit nur einem Location Header mit darin der neuen URL zu senden, an die der Client eine brandneue GET-Anfrage senden muss. 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
  • Client sendet eine HTTP-Anfrage an newpage.xhtml (diese wird in der Browser-Adressleiste angezeigt!)
  • Der Server sendet eine HTTP-Antwort mit dem Inhalt von newpage.xhtml .

Sie können es mit dem integrierten / Add-on-Entwickler-Toolset des Webbrowsers verfolgen. Drücke F12 in Chrome / IE9 / Firebug und überprüfe den Abschnitt “Netzwerk”, um es zu sehen.

Der JSF Navigationhandler sendet keine Weiterleitung. 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 von newpage.xhtml .

Da die ursprüngliche HTTP-Anfrage jedoch auf ” somepage.xhtml , bleibt die URL in der Browser-Adressleiste unverändert. Wenn Sie mit der grundlegenden Servlet-API vertraut sind, sollten Sie verstehen, dass dies die gleiche Wirkung wie RequestDispatcher#forward() .


Ob das Ziehen der HttpServletResponse unter den JSF-Hauben und das Aufrufen von sendRedirect() darauf sendRedirect() ist; Nein, das ist nicht die richtige Verwendung. Ihre Serverprotokolle werden mit IllegalStateException s IllegalStateException weil Sie JSF auf diese Weise nicht IllegalStateException , dass Sie die Kontrolle über die Antwortbehandlung bereits übernommen haben und JSF daher seinen Standardantwortbehandlungsjob nicht ausführen sollte. Sie sollten tatsächlich FacesContext#responseComplete() ausführen.

Jedes Mal, wenn Sie etwas aus dem Paket javax.servlet.* In ein JSF-Artefakt wie eine Managed Bean importieren müssen, sollten Sie unbedingt aufhören, Code zu schreiben und zweimal überlegen, ob Sie wirklich die Dinge richtig machen und sich fragen, ob es da ist Es ist noch kein “Standard-JSF-Weg” für alles, was Sie erreichen wollen und / oder ob die Aufgabe wirklich in einer JSF-verwalteten Bean gehört (es gibt nämlich einige Fälle, in denen ein einfacher Servlet-Filter ein besserer Platz wäre).

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

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

Oder Sie verwenden 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 bei IOException keinen try-catch IOException , lassen Sie die Exception nur durch throws laufen, der servletcontainer wird 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 Navigations-Handler für “plain HTML” -Dateien fehlschlägt, liegt einfach daran, dass der Navigations-Handler nur JSF-Ansichten verarbeiten kann, keine anderen Dateien. Sie sollten dann ExternalContext#redirect() .

Siehe auch:

  • Wie navigiere ich in JSF? Wie man die URL zur aktuellen Seite (und nicht zur vorherigen) macht
  • Wann sollte ich h: outputLink anstelle von h: commandLink verwenden?