Zapisywanie danych do sesji w JSF

Jestem nowy w świecie J(2)EE i tworzenia aplikacji internetowych, ale szybko poruszam się po nim i dużo się uczę. Każdy dzień to dla mnie fantastyczna podróż nowych odkryć.

Obecnie pracuję nad projektem, w którym używam Visual JSF Woodstock na GlassFish v2. Ja też jestem całkiem nowy w JSF.

Są chwile, kiedy muszę zapisać niektóre obiekty (na przykład MyObject) pomiędzy żądaniami. I z tego co do tej pory przeczytałem i zrozumiałem, muszę używać sesje, aby zapisać te obiekty między różnymi żądaniami. Jak na razie dobrze.

Dokładnie, jak to zrobić, tutaj leży moje zmartwienie. Wiem, że w JSP można użyć session.setAttribute("myObj", myObject), który zapisywałby obiekt po stronie klienta za pomocą ciasteczek lub przepisywania url lub ukrytych zmiennych formularza.

Z drugiej strony, w JSF używam Session scoped beans, powiedzmy SessionBean1 dla np., i zapisuję obiekty jako właściwości SessionBean1 (np. SessionBean1.setSomeOjb(myObj)). Czy to dobry sposób, aby to zrobić?

Zgaduję to zrobienie tego w ten sposób spowoduje zwiększone wykorzystanie pamięci na końcu serwera, ponieważ każde żądanie utworzy nową instancję session scoped bean, SessionBean1 oraz pamięć używaną przez zapisane wystąpienia myObject w SessionBean1.

Przeczytałem, że można użyć FacesContext.getExternalContext().getSession/getSessionMap(), który zapisywałby zmienne sesji po stronie klienta.

Więc jaką metodę sugerujesz użyć-session scoped bean lub sessionmap, aby zapisać obiekty do dostępu między żądaniami dla sesja?

Dzięki.
Author: Francois Bourgeois, 2009-08-15

3 answers

Ogólnie aplikacje internetowe Java EE zwykle nie oczekują zapisywania danych sesji po stronie klienta. Masz rację, że martwisz się nadmuchem sesji po stronie serwera, częstym problemem jest posiadanie ogromnych footprintów sesji, które mogą powodować znaczące problemy z zasobami i wydajnością, i mogą być szczególnie w środowiskach klastrowych.

I ' d like to know where you see

Czytałem, że możesz używać FacesContext.getExternalContext ().getSession/getSessionMap (), który zapisuje zmienne sesji po stronie klienta.

Wierzę (popraw mnie w tym punkcie), że to po prostu daje dostęp do obiektu HttpSession, na którym można następnie użyć tego samego

 session.setAttribute("myObj", myObject)

To samo w sobie nie odsyła obiektu z powrotem do klienta, jest on przechowywany na serwerze i kluczowany przez jakiś identyfikator sesji, zwykle przekazywany w pliku cookie.

Teraz są dwie inne techniki: możesz wyraźnie wybrać umieszczenie danych w pliku cookie własnej produkcji-API servlet, które możesz uzyskać dostęp z JSF lub JSP, lub możesz użyć ukrytych pól w formularzach, a tym samym przekazać dane sesji aorund.

Ale rozważ to. Zasada na serwerze aplikacji, której używam, polega na tym, że HttpSession rzędu 1k-4k nie stanowi problemu. Większe niż to (I widziałem sesje mierzone w megabajtach) podkreślają infrastrukturę. Jeśli obawiasz się sesji o takiej wielkości, spodziewasz się przesłania megabajtów danych w pliku cookie lub ukrytym polu z powrotem do przeglądarki na każde żądanie? Nawet 1k-2k jest chyba trochę duży.

Więc rekomendacje:

  1. To proste. Użyj API sesji lub jego manifestacji JSF.

  2. Kontroluj ilość danych w sesji.

Dodany w odpowiedzi na pytanie o klastrowanie:

Zazwyczaj w środowisku klastrowym mamy powinowactwo sesji, więc żądania są wysyłane z powrotem do tego samego członka klastra. Jednak nadal musimy rozważ przypadek (być może jeśli członkowie klastra zawiodą), gdy żądanie trafi do innego serwera.

Niektórzy dostawcy serwerów aplikacji oferują replikację sesji poprzez bezpośrednią komunikację między serwerami lub utrzymywanie sesji w bazie danych - oczywiście są tu koszty ogólne, Więc czasami w przypadku sesji o niskiej wartości akceptujemy utratę sesji w przypadku awarii.

Istnieje argument, że jeśli dane sesji mają wysoką wartość, to powinny być utrzymywane przez aplikacji, to w rzeczywistości dane biznesowe i powinny być traktowane jako takie. Coraz częściej wykorzystywane są do tego bazy danych NOSQL, takie jak Cloudant czy MongoDb. W takim przypadku możemy myśleć o sesji HTTP jako pamięci podręcznej, wiedząc, że dane sesji mogą być pobrane w przypadku błędu.

Argumentowałbym więc, że koszyk może mieć znaczną wartość dla firmy; reprezentuje klientów przemyślane gromadzenie rzeczy, na które chcą wydać pieniądze. Więc powinno się wytrwać, zamiast po prostu trzymać w sesji. Gdy zdecydujemy się ją utrzymać, okaże się, że prowadzi to do innych ciekawych scenariuszy, takich jak skonsolidowane doświadczenie na wielu urządzeniach klienckich. Klient rozpoczyna zakupy w domu na komputerze stacjonarnym, ale dokonuje zakupu online.

Więc kolejna zasada:

3). Nie nadużywaj sesji HTTP tylko dlatego, że tam jest. Zastanów się nad wartością biznesową danych i czy należy je utrzymywać.

 21
Author: djna,
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
2015-08-12 05:49:53

Pracuję nad projektem uniwersytetu z moimi kolegami, jest web jak GoogleImage Labeler. Cóż, mamy więc Kontroler UserController, z jego metodami login, logout, itp... a sesja wygląda tak:

@ManagedBean(name = "userController")
@SessionScoped

Ok, to jest to, co Kreator NetBeans tworzy dla Ciebie.

Nasz sposób tworzenia i zarządzania sesją to:

Przy metodzie rejestru (w której używamy atrybutów formularza w XHTML...) utrzymujemy użytkownika w DB, a następnie dodajemy wartości w sesji:

FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getSessionMap().put("user", current);

Gdzie "current" to Użytkownik (oczywiście zalogowany użytkownik). Mamy to samo w metodzie logowania .

W metodzie logout mamy:

FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
Mam nadzieję, że to ci pomoże.
 14
Author: Carlos Vega,
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
2013-12-18 04:25:22

Więc jaką metodę sugerujesz użyć-session scoped bean lub sessionmap, aby zapisać obiekty do dostępu między żądaniami sesji?

Te dwie rzeczy przechowują dane dokładnie w tym samym miejscu.
<managed-bean>
  <managed-bean-class>foo.Bar</managed-bean-class>
  <managed-bean-name>bar</managed-bean-name>
  <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Po odwołaniu się do wyrażenia, można programowo wyszukać "bar" za pomocą zewnętrznego kontekstu.

FYI: w JSF2 deklaracja może zostać usunięta i zastąpiona adnotacjami:

@ManagedBean(name="bar") @SessionScoped
public class Bar {
...
 2
Author: McDowell,
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
2009-08-15 19:38:44