Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to put data in session variable and get the data in different page in vaadin?

I think I should use the application scope session to deal with that. But I do not have any experience about that. I tried different ways I got from the internet like:

HttpServletRequest request;
HttpSession sess = request.getSession();
sess.setAttribute("name", name);

later in other page
HttpServletRequest request;
String=(String)request.getAttribute(name); 
//or HttpSession sess = request.getSession();
// sess.getAttribute(name);

all do not work. I think there may something special for vaadin to deal with that. Please help me.

like image 496
Kurt X Avatar asked Mar 15 '13 18:03

Kurt X


2 Answers

Two Levels Of Scope

See this posting by Roland Krüger about level of scope in Vaadin 7 with VaadinSession and UI classes. He includes a comparison to Vaadin 6. Good article except that the discussion of manual locking is outmoded as of Vaadin 7.1 (see my comment on that page, and see my answer to a similar question).

Understand that while the bulk of Vaadin 6 & Vaadin 7 are similar or the same, on this topic 6 & 7 are entirely different, with different architecture and different classes involved.

Note that we are discussing VaadinSession, not the HTTP or Servlet session. VaadinSession wraps or contains the Servlet session, so we need not concern ourselves with the Servlet level.

This VaadinSession represents the work-session of a single user. A user has one or more windows/tabs open (UI instances).

Diagram showing how your entire Vaadin app is tied up in an instance of VaadinSession, and that VaadinSession owns one or more UI instances. State can be placed on either, for two levels of scope (app-wide or one browser window/tab).

That diagram above is a bit over-simplified. Here's a more detailed one.

detailed diagram of class hierarchy of Servlet and Vaadin session

Multiple Windows

Vaadin 7 supports multiple browser windows/tabs open on the same Vaadin app. This is a major change in architecture from Vaadin 6.

Content of each browser window/tab is an instance of your UI subclass. All of those instances belong to the same VaadinSession. If the user clicks the reload feature on the browser window/tab, the UI instance is destroyed and a new one instantiated. But the VaadinSession endures. Adding the @PreserveOnRefresh annotation changes that behavior to retain the same UI instance, but that is beside the point.

The point is that Vaadin 7 has two levels of scope:

  • VaadinSession (your whole app)
  • UI (each browser window/tab).

You may want to store data at either level. For example, user login/authentication info should go in the VaadinSession.

Putting State on UI

To store data on the UI, add fields or collections to your UI subclass. Simple and obvious.

Putting State On VaadinSession

To store data on the VaadinSession, call setAttribute and getAttribute. You will have to cast the results. Simple, except for one catch: thread-safety.

Thread-Safety

You can manually mange locking to protect the VaadinSession concurrently. But Vaadin will do provide that thread-safety protection for you if you follow the documented rules.

Main Thread

If modifying the VaadinSession from the usual main user interface thread, no issue. Most everything you do in Vaadin from the main thread is already affecting the VaadinSession object. That's where your app lives. So thread-safe locking is already automatically provided by Vaadin.

Other Threads

If using the VaadinSession from another thread, make your call in a Runnable you pass to the access method on either the UI or the VaadinSession object. If affecting any user interface layout or widgets in addition to the session, call the access method on the UI method. If affecting only the session and not the user interface, pass your Runnable the access method on the VaadinSession.

Third Level of Scope: App-Wide

FYI, you can use a wider scope. If you have "global" data or objects to share app-wide across all the users’ sessions, you can access the ServletContext object. "Context" means the world of your web app, the stuff your web app can access. Your Vaadin app has a single ServletContext object automatically instantiated by your Servlet container. Call the pair of methods, getAttribute and setAttribute, to store any Object you have.

For more information, see this Question & Answer of mine, How to access ServletContext from within a Vaadin 7 app?.

To sum it up in text (and diagram below): A Servlet container such as Tomcat or Jetty can run one or more Vaadin web apps. Each web app has a single ServletContext object automatically managed by the container, where get/setAttribute methods can store any Objects of your choice. Each Vaadin web app has one VaadinSession object for each user’s current work-session. Each VaadinSession object contains one or more UI subclass instances, representing the content seen within a web browser’s window/tab (or a Portlet view area). Each UI subclass instance can have any number of member variables, like any POJO.

Diagram of Servlet container with one or more Vaadin apps, each with a single ServletContext instance


Tip: your Runnable can use the new shorter Lambda syntax in Java 8 if you want. NetBeans 8 will even suggest that.

like image 178
Basil Bourque Avatar answered Nov 13 '22 20:11

Basil Bourque


Vaadin is designed to make this problem very easy to solve, and it helps to not think about the normal http request/response cycle here.

In the typical Vaadin webapp (6 or 7) you have a class that handles the first connection to the webapp (in 7 you extend the UI class). From that first connection all you need to do is store the information you want to keep in any way you would in a normal app -- variable, map, list, plain old java object (POJO), etc. Say you use a POJO. That object is just like any other Java object. Hold it in a variable accessible by any object that needs it. If you've added any kind of interactivity to the webapp, the user will 'enter' the application again through that interactive component (say a Button listener). From that button listener you can access the POJO you created earlier in the user's 'session.'

That's it. It's actually surprisingly simple, and doesn't involve you ever touching http (unless you want to later). And certainly not threadlocals for this level of storage.

like image 40
Christopher Poile Avatar answered Nov 13 '22 21:11

Christopher Poile