Ala*_*Dee 32 java-ee ejb-3.0 jsf-2
我正在使用JSF,PrimeFaces,Glassfish和Netbeans构建我的第一个Java EE应用程序.因为我是新手,所以我可能会接近核心问题.
核心问题:我想安全地维护用户的信息.关于是否应该在JSF会话bean或有状态会话EJB中维护它似乎存在矛盾的想法.我正在尝试使用有状态会话EJB,因为它更安全.
问题是我的应用程序似乎正在创建该bean的多个实例,当我希望它创建一个并重新使用它时.如果我刷新页面它运行@PostConstruct和@PostActivate3次,他们都用不同的实例.然后,当我重新部署应用程序时,它们都会被破坏.
我误解了它应该如何工作或错误配置了什么?
我将尝试显示一个修剪过的代码示例:
basic.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
<c:if test="#{loginController.authenticated}">
Authenticated
</c:if>
<c:if test="#{loginController.authenticated}">
Authenticated
</c:if>
<c:if test="#{loginController.authenticated}">
Authenticated
</c:if>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
LoginController:
@Named(value = "loginController")
@RequestScoped
public class LoginController implements Serializable {
@EJB
private UserBeanLocal userBean;
public boolean isAuthenticated() {
return userBean.isAuthenticated();
}
}
Run Code Online (Sandbox Code Playgroud)
UserBean(不包括UserBeanLocal界面)
@Stateful
public class UserBean implements UserBeanLocal, Serializable {
boolean authenticated = false;
@PostConstruct
@PostActivate
public void setup(){
System.out.println("##### Create user Bean: "+this.toString());
}
@Override
public boolean isAuthenticated() {
System.out.println("########## Authentication test is automatically passing.");
authenticated = true;//hard coded for simplicity.
return authenticated;
}
@PrePassivate
@PreDestroy
public void cleanup(){
System.out.println("##### Destroy user Bean");
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是刷新三次后的Glassfish输出:
INFO: ##### Create user Bean: boundary._UserBean_Serializable@2e644784
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ##### Create user Bean: boundary._UserBean_Serializable@691ae9e7
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ##### Create user Bean: boundary._UserBean_Serializable@391115ac
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 59
有状态会话bean(SFSB)并不完全符合您的想法.您似乎认为它们的行为类似于会话作用域的JSF托管bean.这是不真实的.EJB中的术语"会话"与您考虑过的HTTP会话具有完全不同的含义.
必须在事务上下文中解释EJB中的"会话".只要客户端存在,事务(基本上是数据库会话)就会出现在SFSB的情况下.SFSB的客户端在您的特定示例中不是 webbrowser,而是JSF托管bean实例本身,恰好是注入SFSB的实例.由于您已将JSF托管bean放在请求范围内,因此将在每个HTTP请求上与JSF托管bean一起重新创建SFSB.
例如,尝试将JSF托管bean放在视图范围中.例如,视图范围对于同一页面上的多步骤表单很有用.每次当视图回发到自身时,将重用相同的JSF托管bean实例,并且此实例允许您访问与创建bean时相同的SFSB实例,该实例不在其他地方共享.只要客户端(视图作用域的JSF托管bean)存在,SFSB事务就会存在.
无状态会话bean(SLSB)可以在其他地方共享,但这无关紧要,因为无论如何它都被视为无状态.这个"功能"节省了容器时间和内存来创建和存储它们.容器可以只有一个池.更重要的是,在视图,会话或应用程序范围内的JSF托管bean中注入的SLSB实例不一定需要在每个HTTP请求上引用与在JSF托管bean创建期间完全相同的实例.它甚至可以是完全不同的实例,具体取决于容器池中的可用实例.只要在SLSB上调用单个方法,事务就会生效(默认情况下).
也就是说,SFSB不适合您"记住登录用户"的特殊情况.它"更安全"真的没有意义.只需将JSF托管bean放在会话范围内,让它自己记住登录用户,并使用SLSB执行任何业务操作(例如与DB交互),并仅在需要真实状态时使用SFSB 会话bean(我假设你现在明白它们到底是什么:)).
| 归档时间: |
|
| 查看次数: |
13891 次 |
| 最近记录: |