7

我想我应该使用应用程序范围会话来处理这个问题。但我对此没有任何经验。我尝试了从互联网上获得的不同方式,例如:

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 可能有一些特别的东西可以处理。请帮我。

4

3 回答 3

14

两个级别的范围

请参阅Roland Krüger 的这篇文章,了解 Vaadin 7 中的范围级别以及VaadinSessionUI类。他包含了与 Vaadin 6 的比较。好文章除了手动锁定的讨论在 Vaadin 7.1 中已经过时(请参阅我在该页面上的评论,并查看对类似问题的回答)。

了解虽然 Vaadin 6 和 Vaadin 7 的大部分内容相似或相同,但在这个主题上 6 和 7 完全不同,涉及不同的架构和不同的类。

请注意,我们讨论VaadinSession的是 HTTP 或Servlet 会话。VaadinSession 包装或包含 Servlet 会话,因此我们不必关心 Servlet 级别。

此 VaadinSession 代表单个用户的工作会话。用户打开了一个或多个窗口/选项卡(UI实例)。

该图显示了您的整个 Vaadin 应用程序如何绑定在 VaadinSession 的一个实例中,并且该 VaadinSession 拥有一个或多个 UI 实例。 状态可以放置在两个级别的范围(应用程序范围或一个浏览器窗口/选项卡)中。

上图有点过于简单了。这里有一个更详细的。

Servlet 和 Vaadin 会话的类层次结构详图

多个窗口

Vaadin 7 支持在同一个 Vaadin 应用程序上打开多个浏览器窗口/选项卡。这是 Vaadin 6 架构的重大变化。

每个浏览器窗口/选项卡的内容是您的UI子类的一个实例。所有这些实例都属于同一个VaadinSession. 如果用户单击浏览器窗口/选项卡上的重新加载功能,该UI实例将被销毁并实例化一个新实例。但VaadinSession经久不衰。添加@PreserveOnRefresh注释会更改该行为以保留相同的 UI 实例,但这不是重点。

关键是 Vaadin 7 有两个级别的范围:

  • VaadinSession(你的整个应用程序)
  • UI(每个浏览器窗口/选项卡)。

您可能希望在任一级别存储数据。例如,用户登录/身份验证信息应该放在 VaadinSession 中。

开启状态UI

要在 UI 上存储数据,请将字段或集合添加到 UI 子类。简单明了。

开启状态VaadinSession

要在 VaadinSession 上存储数据,请调用setAttributegetAttribute. 您将不得不转换结果。很简单,除了一个问题:线程安全。

线程安全

您可以手动管理锁定以同时保护 VaadinSession。但是,如果您遵循记录在案的规则,Vaadin 会为您提供线程安全保护。

主线程

如果从通常的主用户界面线程修改 VaadinSession,则没有问题。您从主线程在 Vaadin 中所做的大多数事情都已经影响到 VaadinSession 对象。这就是您的应用程序所在的位置。因此,线程安全锁定已经由 Vaadin 自动提供。

其他主题

如果从另一个线程使用 VaadinSession,请在Runnable中进行调用,然后将其传递给accessUI 或 VaadinSession 对象上的方法。如果影响除了会话之外的任何用户界面布局或小部件,请access在 UI 方法上调用该方法。如果只影响会话而不影响用户界面,请将您的 Runnableaccess方法传递给 VaadinSession。

第三级范围:应用程序范围

仅供参考,您可以使用更广泛的范围。如果您有“全局”数据或对象要在所有用户的会话中共享应用程序范围,则可以访问该ServletContext对象。“上下文”是指你的网络应用程序的世界,你的网络应用程序可以访问的东西。您的 Vaadin 应用程序有一个ServletContext由您的 Servlet 容器自动实例化的对象。调用这对方法 ,getAttributesetAttribute, 来存储Object你拥有的任何东西。

有关更多信息,请参阅我的这个问答,如何ServletContext从 Vaadin 7 应用程序中访问?.

用文字总结(和下图):一个 Servlet 容器,如 Tomcat 或 Jetty 可以运行一个或多个 Vaadin Web 应用程序。每个 Web 应用程序都有一个ServletContext由容器自动管理的对象,其中get/setAttribute方法可以存储您选择的任何对象。每个 Vaadin Web 应用程序VaadinSession对于每个用户的当前工作会话都有一个对象。每个VaadinSession对象包含一个或多UI个子类实例,表示在 Web 浏览器的窗口/选项卡(或 Portlet 视图区域)中看到的内容。每个UI子类实例可以有任意数量的成员变量,就像任何POJO一样。

带有一个或多个 Vaadin 应用程序的 Servlet 容器示意图,每个应用程序都有一个 ServletContext 实例


提示:如果您愿意,您的 Runnable 可以使用 Java 8 中新的更短的 Lambda 语法。NetBeans 8 甚至会建议这样做。

于 2014-08-30T20:30:20.407 回答
2

Vaadin 旨在使这个问题很容易解决,并且在这里不必考虑正常的 http 请求/响应周期是有帮助的。

在典型的 Vaadin webapp(6 或 7)中,您有一个处理与 webapp 的第一个连接的类(在 7 中,您扩展了 UI 类)。从第一个连接开始,您需要做的就是以您在普通应用程序中的任何方式存储您想要保留的信息——变量、映射、列表、普通的旧 java 对象 (POJO) 等。假设您使用 POJO。该对象与任何其他 Java 对象一样。将它保存在任何需要它的对象都可以访问的变量中。如果您向 web 应用程序添加了任何类型的交互性,用户将通过该交互性组件(例如 Button 侦听器)再次“进入”应用程序。从该按钮侦听器中,您可以访问您之前在用户的“会话”中创建的 POJO。

而已。它实际上非常简单,并且不涉及您接触 http(除非您以后想要)。对于这种存储级别,当然不是 threadlocals。

于 2013-03-19T23:11:14.260 回答
1

您可以使用 ThreadLocal 变量来保存您的数据。然后,您从变量中获取数据并清理它。不要忘记将您的变量设为 public 和 static 以便从另一个类中访问它。

于 2013-03-19T10:01:52.990 回答