2012-02-16 16 views
9

Czy istnieje sposób dołączenia globalnego odbiornika do wszystkich wywołań AJAX w JSF? Może przez słuchacza fazy czy coś takiego?Korzystanie z JSF 2.0/Facelets, czy istnieje sposób na dołączenie globalnego detektora do wszystkich wywołań AJAX?

Oto zagadka ... Powiedzmy, że używasz tagów f: ajax i czegoś w stylu apache shiro, a Twoja sesja wygasa. Następnie wróć i kliknij przycisk z dołączonym f: ajax. Serwer zareaguje przekierowaniem 302 na stronę logowania.

Użytkownik nic nie widzi. Mogą wielokrotnie klikać i wywoływać wywołania ajax, ale dla nich aplikacja jest po prostu "martwa".

Więc, moim zdaniem jest, czy istnieje sposób na dołączenie detektora do wszystkich wywołań ajaxowych w JSF? Jeśli tak, chciałbym monitorować kod odpowiedzi. Jeśli jest to przekierowanie, użyj okna.navigate, aby wysłać je po drodze.

Jestem zawsze otwarty, aby usłyszeć, jak inni rozwiązali ten problem! Dzięki!

+0

wont [ „stan początkowy zapisywania na serwerze i na sesji transferowej stanie czas oczekiwania do klienta przez cały czas reakcji”] (http://stackoverflow.com/questions/10378133/initial-state-saving-to-server -on-session-timeout-transfer-to-client-for-all-t) jest lepszym rozwiązaniem niż te wszystkie hacky? Zastanawiam się, dlaczego JSF już tego nie zapewnia i czy mogę jakoś to zaimplementować. –

Odpowiedz

16

Czy istnieje sposób, aby dołączyć do globalnego słuchacza wszystko AJAX wywołuje w JSF? Może przez słuchacza fazy czy coś takiego?

Tak, PhaseListener może to zrobić. A także SystemEventListener. A także Filter.

Jeśli znajdujesz się w kontekście JSF, możesz sprawdzić, czy bieżące żądanie jest żądaniem ajaxowym, czy nie.

if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) { 
    // It's an ajax request. 
} 

Jeśli nie jesteś wewnątrz kontekstu, np JSF wewnątrz Filter, możesz sprawdzić, czy bieżące żądanie jest żądaniem JSF ajax, czy nie.

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) { 
    // It's a JSF ajax request. 
} 

Oto zagadka ... Powiedzmy, że używasz f: ajax tagi i coś takiego jak apache Shiro i niech Twoja sesja wygaśnie. Następnie wróć i kliknij przycisk z dołączonym f: ajax. Serwer zareaguje przekierowaniem 302 na stronę logowania.

Użytkownik nic nie widzi. Mogą wielokrotnie klikać i wywoływać wywołania ajax, ale dla nich aplikacja jest po prostu "martwa".

wymuszanie przekierowanie na ajax żądanie wymaga specjalnego odpowiedzi XML. Kiedy znajdujesz się w kontekście JSF, wtedy ExternalContext#redirect() bierze to już domyślnie pod uwagę. Wystarczy wpisać:

FacesContext.getCurrentInstance().getExternalContext().redirect(url); 

Jeśli nie ma Cię w kontekście JSF, np. wewnątrz Filter, musisz sam napisać całą odpowiedź XML. Na przykład.

response.setContentType("text/xml"); 
response.getWriter() 
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") 
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url); 
+0

TSo Zgaduję, że optymalną trasą jest napisanie filtra znajdującego się przed filtrem Shiro. Kiedy Shiro wysyła przekierowanie, mój filtr przechwytuje go i wysyła XML. Mam przeczucie, że nie mogę tego zrobić w aplikacji twarze, ponieważ Shiro będzie blokować prośbę. –

+0

Najlepszym rozwiązaniem jest filtr przed filtrem Shiro. – BalusC

+1

Dla twojej informacji, napisałem o tym właśnie blogu i dostarczyłem kompletny, gotowy do użycia filtr dla Shiro: http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for- java-ee-6.html # MakeShiroJSFAjaxAware – BalusC

4

Aby przekierować żądania JSF ajax trzeba xml następująco

<?xml version="1.0" encoding="UTF-8"?> 
<partial-response> 
     <redirect url="XXX"> 
     </redirect> 
</partial-response> 

Tutaj XXX url chcesz przekierować wydarzy.

Na przekierowanie połączenia ajax nie jest tak jak powyżej, więc nie przekierowania.

Aby uzyskać pożądany rezultat mieć filtr dla wszystkich JSF wniosek wyjątkiem kilku stron (strona logowania) i sprawdzić sesja jest ważna, a jeśli jest to naprawdę JSF ajax wywołanie sprawdzając nagłówek „Twarze-request”, jego wartość powinna być "częściowa/ajax". Jeśli sesja wygasła i jest żądanie ajax wysłać powyżej xml jako odpowiedź.

Powinno działać.

+0

Wont ["Zapis stanu początkowego do serwera i stan transferu limitu czasu sesji do klienta na cały czas reakcji"] (http://stackoverflow.com/questions/10378133/initial-state-saving-to-server-on-session- timeout-transfer-to-client-for-all-t) jest lepszym rozwiązaniem niż te wszystkie hacky? Zastanawiam się, dlaczego JSF już tego nie zapewnia i czy mogę jakoś to zaimplementować. –

Powiązane problemy