而如果输入错误的用户注册信息,Bean validation 规范会检出输入错误,AccountCreate.jsp 中显示错误提示。如图 20 所示。
利用 CDI 和 JSF2.0 简化 Account Login 程序开发
JSR299 Contexts and Dependency Injection (CDI) 进一步提高了 Java EE 开发平台的易用性,提供了包括上下文管理,类型安全的依赖注入,拦截器绑定,与 JSF 的集成等服务。详情参考”Dependency Injection in Java EE 6 系列文章”
JSF314 JSF2.0 则关注与 Web 应用的开发,以提高 Web 应用开发效率、降低维护复杂度为目标,并加入 Ajax 支持,Bean Validation 支持。详情参考”JSF2 简介系列文章“。
在 JSF2.0 中,通过 Expression Language (EL) 表达式语言与 @ManagedBean 注释,将 Web 页面与 Backing Bean 关联在一起,参考清单 10。
JSF 表单: <h:inputText styleClass=”inputText” id=”username” value=”#{account.username}”> ManagedBean @ManagedBean(name=”account”) Public class Accountbean { Private String username …. } |
借助 CDI 服务,我们可以用 @Named 注释替代 @ManagedBean,将 CDI 引入 JSF backing bean 中,从而实现 JSF 与 CDI 的集成。
在本章中,我们将采用 CDI+JSF 的方式重写 Account Login 程序,用 JSF 替代原有的 JSP 和 Servlet 实现表现层,并利用 CDI 特性更新原有的 EJB session bean。涉及的主要步骤为:
启用 CDI 服务
CDI 上下文管理 @..Scoped
CDI 依赖注入 @Inject
JSF 2.0 Facelets 开发
CDI 与 JSF 集成
依照 JSR299 规范,开发人员必须在 .war 归档文件的 WEB-INF/ 目录下或者其他类型归档文件的 META-INF/ 目录下,放置 beans.xml 文件。参考清单 11:
<?xml version=”1.0″ encoding=”UTF-8″?> <beans xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd”> </beans> |
此外,CDI Bean 必须包含一个无参数的构造函数,或者其构造函数用 @Injection 修饰;CDI Bean 不能是抽象类(@Decorator CDI bean 除外);CDI Bean 不能是非静态内部类。使用 CDI 服务时,请尽可能保证您的 bean 是可序列化的(implements Serializable)。
CDI 上下文管理 @..Scoped 服务
CDI 管理的每个对象的 Scope 和生命周期都被绑定到特定的上下文中。表 1 列出了 CDI 支持的上下文。
范围 |
描述 |
Dependent | CDI 默认范围,任何注入对象都默认依赖于其被注入的上下文 |
ApplicationScoped | 在应用程序范围内存储对象;例如,当数据在 Application 级别共享时,可以用 @ApplicationScoped 描述 |
RequestScoped | 在请求范围内存储对象;例如,当数据用于将 HTTP 请求传递到 JSF backing bean 中,可以用 @RequestScoped 描述 |
SessionScoped | 在会话范围内存储对象;例如,当用户登录凭据需要在整个 session 级别共享,可以用 @SessionScoped |
ConversationScoped | 当请求和会话范围皆不适用,可以利用 ConversationScoped 自定义上下文。 |
在 Accout Login 程序中,EJB session bean AccountService 用于存储用户登陆凭信,因此我们可以用 @SessionScoped 描述 AccountService session bean,参考清单 12:
清单 12. SessionScoped EJB session bean
@Stateful @Named @SessionScoped public class AccountService implements Serializable { …. } |
用户在登录界面中会输入用户名 username、密码信息 password,这两个数据会传递到 JSF backing bean 中,用于触发后续操作。由于 username 和 password 仅出现在 HTTP request 中,用 @RequestScoped 描述更适当。我们新建一个名为 Credentials.java 的 POJO 对象,存储 username 和 password,参考清单 13。
清单 13. RequestScoped Credentials.java
@Named @RequestScoped public class Credentials implements Serializable { private static final long serialVersionUID = 1375763091581287708L; private String username; private String password; public Credentials() { super(); } Getters & Setters …. } |
在 CDI Bean 中,我们不仅可以通过 @Resource 等注释将资源注入到 Java Bean,还可以通过 @Injection 注释将任何 Java Bean 注入。
在 AccountService bean 中,我们将 Usertab 对象注入,用于存储用户登录凭信,将 Credentials 对象注入,用于用户登录信息的验证。通过 @Inject,我们不需要关心对象的创建、销毁等额外工作。参考清单 14:
@Stateful @Named @SessionScoped public class AccountService implements Serializable { private static final long serialVersionUID = 7103565672729007156L; @PersistenceContext(unitName = “AccountManagementEJB”) EntityManager em; @Inject private Usertab user; @Inject private Credentials credential; …. public AccountService() { super(); }
public String login() { user = this.loginUser(credential.getUsername(),credential.getPassword()); if (user != null) return (“AccountInfo.jsf”); else return (“AccountLogin.jsf”); } public Usertab loginUser(String username, String password) { …. }
Getters() & Setters()…
} |
以下文章点击率最高
Loading…