我认为我应该使用应用程序作用域会话来处理该问题。但是我对此没有任何经验。我尝试了不同的方式,例如:
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);
都行不通。我认为vaadin可能需要处理一些特殊的事情。请帮我。
最佳答案
范围的两个层次
有关Vaadin 7中具有this posting和VaadinSession类的作用域级别,请参见RolandKrüger的UI。他提供了与Vaadin 6的比较。不错的文章,但自Vaadin 7.1起,有关手动锁定的讨论已过时(请参阅我在该页面上的评论,并参阅my answer的类似问题)。
可以理解,虽然Vaadin 6和Vaadin 7的大部分内容相似或相同,但在此主题6和7上却完全不同,涉及的体系结构和类别也不同。
请注意,我们正在讨论的是VaadinSession
,而不是HTTP或Servlet session。 VaadinSession包装或包含Servlet会话,因此我们不必关心Servlet级别。
此VaadinSession代表单个用户的工作会话。用户有一个或多个打开的窗口/选项卡(UI
实例)。
上面的图有点过分简化了。这是更详细的一个。
多视窗
Vaadin 7支持在同一Vaadin应用程序上打开多个浏览器窗口/选项卡。这是Vaadin 6架构上的重大变化。
每个浏览器窗口/选项卡的内容是您的UI
子类的实例。所有这些实例都属于同一个VaadinSession
。如果用户单击浏览器窗口/选项卡上的重新加载功能,则UI
实例将被销毁并实例化一个新实例。但是VaadinSession
可以忍受。添加@PreserveOnRefresh
annotation会更改该行为以保留相同的UI实例,但这并不重要。
关键是Vaadin 7具有两个级别的范围:VaadinSession
(您的整个应用)UI
(每个浏览器窗口/标签)。
您可能要在任一级别上存储数据。例如,用户登录/身份验证信息应放在VaadinSession中。
将状态置于UI
要将数据存储在UI上,请将字段或集合添加到UI子类。简单明了。
将状态置于VaadinSession
要将数据存储在VaadinSession上,请调用setAttribute
和getAttribute
。您将不得不转换结果。简单,除了一个陷阱:线程安全。
线程安全
您可以手动进行锁定以同时保护VaadinSession。但是,如果您遵循记录的规则,则Vaadin会为您提供该线程安全保护。
主线
如果从通常的主用户界面线程修改VaadinSession,则没有问题。您在主线程中的Vaadin中所做的大多数事情已经在影响VaadinSession对象。那就是您的应用程序所在的地方。因此,Vaadin已经自动提供了线程安全锁定。
其他线程
如果从另一个线程使用VaadinSession,请在Runnable中进行调用,然后将其传递到UI或VaadinSession对象上的access
方法。如果影响除会话之外的任何用户界面布局或小部件,请在UI方法上调用access
方法。如果仅影响会话而不影响用户界面,请在VaadinSession上传递您的Runnable access
方法。
第三级范围:应用范围
仅供参考,您可以使用更广泛的范围。如果您有“全局”数据或对象要在所有用户会话之间在应用范围内共享,则可以访问ServletContext
对象。 “上下文”是指Web应用程序的世界,Web应用程序可以访问的内容。 Vaadin应用程序具有一个ServletContext
对象,该对象由Servlet容器自动实例化。调用方法对getAttribute
和setAttribute
来存储您拥有的任何Object
。
有关更多信息,请参见此问题与解答How to access ServletContext
from within a Vaadin 7 app?。
总结起来(如下图所示):一个Servlet容器(例如Tomcat或Jetty)可以运行一个或多个Vaadin Web应用程序。每个Web应用程序都有一个由容器自动管理的ServletContext
对象,其中get/setAttribute
方法可以存储您选择的任何对象。每个Vaadin网络应用程序针对每个用户的当前工作会话都有一个VaadinSession
对象。每个VaadinSession
对象包含一个或多个UI
子类实例,代表在Web浏览器的窗口/标签(或Portlet视图区域)中看到的内容。每个UI
子类实例可以具有任意数量的成员变量,例如任何POJO。
提示:如果需要,您的Runnable可以使用Java 8中新的较短的Lambda语法。 NetBeans 8甚至会建议这样做。