Cas*_*der 5 java ejb glassfish javabeans cdi
我正在尝试在GlassFish 3上的Java EE JPA应用程序中实现某种审计.
我@EntityListeners
在我的@MappedSuperclass
实体上添加了一个注释,监听器在其方法上有注释@PrePersist
和@PreUpdate
注释,这些注释在运行时被愉快地调用.
在这些方法中,我试图用(@Inject
)一@Named
,@Stateful
,@SessionScoped
豆(UserSession
为了获得当前用户的ID).监听器类根本没有注释.
问题是我无法UserSession
注入豆子; 我总是最终得到一个null
价值.到目前为止,我尝试了总是注入空值的plain .我@Inject UserSession us;
也尝试过UserSession us = (UserSession) ctx.lookup("java:global/application/module/UserSession");
总是返回一个新对象(我验证了构造函数调用,加上对象为空).
我很确定我错过了一些关于CDI非常重要但我无法弄清楚是什么.有人可以指出我正确的方向吗?
我最终找到了一个解决方法,它允许我获得 bean 的引用@Stateful
:
我创建了一个@Named @Singleton @Startup
bean SessionController,它保存了本地HashMap<String, UserSession> sessionMap
的 bean 引用@Stateful
:
@Named
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class SessionController {
private HashMap<String, UserSession> sessionMap;
@PostConstruct
void init() {
sessionMap = new HashMap<String, UserSession>();
}
@PreDestroy
void terminate() {
for (UserSession us : sessionMap.values()) {
us.logoutCleanUp(); //This is annotated as @Remove
}
sessionMap.clear();
}
public void addSession(String sessionId, UserSession us) {
sessionMap.put(sessionId, us);
System.out.println("New Session added: " + sessionId);
}
public UserSession getCurrentUserSession() {
FacesContext context = FacesContext.getCurrentInstance();
String sessionId = ((HttpSession) context.getExternalContext().getSession(false)).getId();
return sessionMap.get(sessionId);
}
Run Code Online (Sandbox Code Playgroud)
}
我在每个 bean 的方法中添加引用@PostConstruct
:
public class UserSession implements Serializable {
@Inject SessionController sc;
...
@PostConstruct
void init() {
FacesContext context = FacesContext.getCurrentInstance();
String sessionId = ((HttpSession) context.getExternalContext().getSession(true)).getId();
sc.addSession(sessionId, this);
}
Run Code Online (Sandbox Code Playgroud)
请注意,这.getSession(true)
是必需的,因为会话可能尚未创建。另请注意,它this
是安全传递的,因为它@PostConstruct
不是构造函数......
所有这些之后,我可以在我的 EntityListener (以及任何其他地方)中获取引用,如下所示:
SessionController sc = (SessionController) new InitialContext().lookup("java:module/SessionController");
UserSession us = sc.getCurrentUserSession();
Run Code Online (Sandbox Code Playgroud)
或者在 CDI 豆中像这样
@Inject SessionController sc;
Run Code Online (Sandbox Code Playgroud)
我看到的唯一缺点是这种方法仅适用于 Web 应用程序(有意义FacesContext context = FacesContext.getCurrentInstance()
)。我的一些 bean(最后是我的 EntityListener)也通过@javax.jws.WebService
as @Stateless
beans 公开。在这种情况下(实际上:没有),我的单例将无法工作(尚未测试),因为没有任何类型的sessionId(确切地说根本没有会话)。我将不得不为此使用一种解决方法,可能使用 bean 的 SessionContext 或发明某种可用的sessionId 。如果我创建了一些可用的东西,我会回复...
归档时间: |
|
查看次数: |
3195 次 |
最近记录: |