Jaka jest różnica między przekierowaniem a nawigacją / do przodu i kiedy z czego korzystać?

Jaka jest różnica między nawigacją w JSF

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

I przekierowanie

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

I jak zdecydować, kiedy użyć czego?

Problem z nawigacją polega na tym, że URL strony nie zmienia się, chyba że faces-redirect=true zostanie dodany do ciągu zapytań URL nawigacji. Jednak w moim przypadku dodanie faces-redirect=true powoduje błąd, jeśli chcę przekierować na stronę inną niż JSF, taką jak zwykła strona HTML.

I inną opcją jest jak zasugerował BalusC w JSF 2.0 redirect error

Author: Community, 2012-07-01

1 answers

Po pierwsze, termin "przekierowanie" jest w świecie web development działaniem wysyłania klientowi pustej odpowiedzi HTTP z tylko Location nagłówkiem z nim nowy adres URL, na który klient ma wysłać zupełnie nowe żądanie GET. Więc zasadniczo:

  • klient wysyła żądanie HTTP do somepage.xhtml.
  • serwer wysyła odpowiedź HTTP z powrotem z Location: newpage.xhtml nagłówkiem
  • klient wysyła żądanie HTTP do newpage.xhtml (jest to widoczne w pasku adresu przeglądarki!)
  • serwer wysyła HTTP odpowiedź z treścią newpage.xhtml.

Możesz go śledzić za pomocą wbudowanego zestawu narzędzi programistycznych webbrowser/addon. Naciśnij F12 w Chrome / IE9 / Firebug i sprawdź sekcję "sieć", aby ją zobaczyć.

JSF navigationhandler nie wysyła przekierowania. Zamiast tego używa zawartości strony docelowej jako odpowiedzi HTTP.

  • klient wysyła żądanie HTTP do somepage.xhtml.
  • serwer wysyła odpowiedź HTTP z zawartością newpage.xhtml.

Jednakże jako oryginalne żądanie HTTP było somepage.xhtml, adres URL w pasku adresu przeglądarki pozostaje niezmieniony. Jeśli jesteś zaznajomiony z basic Servlet API , powinieneś zrozumieć, że ma to taki sam efekt jak RequestDispatcher#forward().


Jeśli chodzi o to, czy wyciągnięcie HttpServletResponse spod kaptura JSF i wywołanie sendRedirect() na nim jest właściwym użyciem; nie, to nie jest właściwe użycie. Twoje logi serwera będą zaśmiecone IllegalStateException S, ponieważ w ten sposób nie powiesz JSF, że już wziąłeś nad kontrolą obsługi odpowiedzi, a tym samym JSF nie powinien wykonywać swojego domyślnego zadania obsługi odpowiedzi. W rzeczywistości powinieneś wykonywać FacesContext#responseComplete() potem.

Ponadto, za każdym razem, gdy musisz zaimportować coś z javax.servlet.* w artefakcie JSF, takim jak managed bean, powinieneś absolutnie przestać pisać kod i zastanowić się dwa razy, czy naprawdę robisz rzeczy we właściwy sposób i zadać sobie pytanie, czy nie istnieje już "standardowy sposób JSF" dla tego, co próbujesz osiągnąć i / lub jeśli zadanie naprawdę należy do zarządzanej przez JSF fasoli(są pewne przypadki, w których prosty filtr serwletów byłby lepszym miejscem).

Prawidłowym sposobem wykonania przekierowania w JSF jest użycie faces-redirect=true ciągu zapytania w wyniku akcji:

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

Lub używając ExternalContext#redirect() jeśli nie znajdujesz się wewnątrz metody akcji, takiej jak metoda ajax lub prerender listener:

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

(tak, nie musisz umieszczać try-catch wokół niego na IOException, po prostu pozwól exception go through throws, servletcontainer się tym zajmie)

Lub używając NavigationHandler#handleNavigation() W szczególnych przypadkach, jeśli używasz przypadków nawigacji XML i / lub niestandardowego programu obsługi nawigacji z wbudowanym słuchaczem:

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

Dlaczego obsługa nawigacji nie działa dla plików "plain HTML", to po prostu dlatego, że obsługa nawigacji może przetwarzać tylko widoki JSF, a nie inne pliki. Powinieneś więc używać ExternalContext#redirect().

Zobacz też:

 79
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:16