小编mar*_*383的帖子

WELD + GF4 + SessionScoped:有时错误的bean?


TL; DR我们@SessionScoped注入了具有另一个会话内容的bean实例


最近我们遇到了两个客户系统的严重问题.我们的客户在具有WELD 2.0.5的Glassfish 4.0服务器的两台机器上运行相同JSF 2.2应用程序的两个独立实例(因内存泄漏而欢呼!).

一些用户一直在报告问题,例如在提交表单后,响应显示的用户名与最初登录的用户名不同.由于我们无法在开发和测试环境中重现此行为,因此我们开始从生产中获取日志数据系统.

我们记录了什么?

在我们第一次尝试时,我们开始记录哪个用户在某个时间从哪个客户进行了哪个操作.爬过日志后,我们发现了如下序列:

Time Client   User   Action
.............................
t=0  ClientA  UserA  Login
t=1  ClientA  UserA  Logoff
t=2  ClientB  UserB  Login
t=3  ClientB  UserB  ActionA
t=4  ClientB *UserA* ActionB
t=5  ClientB  UserB  Logoff
Run Code Online (Sandbox Code Playgroud)

User A在更换发生之前,替换用户(此处)的会话并不总是结束(有时会导致一个用户注销另一个用户......).那么当前登录的用户存储在哪里?我们将它作为属性存储在@SessionScopedbean中,@RequestScoped只要我们需要这些信息,就会将其存入bean中.这导致我们认为@SessionScoped豆类有时会混淆的理论.

@Named
@javax.enterprise.context.SessionScoped
public class SessionStateBean {
  private User user;

  public void setUser(...) { }
  public User getUser() { }
}
Run Code Online (Sandbox Code Playgroud)

因此,在第二次尝试时,我们通过以下功能扩展了日志数据:

  • 我们开始在HTTP会话中存储用户名,并在每个请求中将其与来自@SessionScopedbean 的值进行比较.
  • @SessionScopedbean的每个实例都接收到自己的UUID,并在构造和销毁bean以及更改用户属性时记录.我们知道@SessionScopedbean有可能有多个代理,被钝化等等,但我们试了一下.

关于第一个日志功能,我们开始看到序列显示来自会话范围bean的用户名与存储在HTTP会话中的值之间的实际差异: …

session jsf glassfish cdi weld

7
推荐指数
1
解决办法
1145
查看次数

标签 统计

cdi ×1

glassfish ×1

jsf ×1

session ×1

weld ×1