之前按照EJB3.0书籍写了一个新闻发布系统的简单例子,隔了很多天再重新发布发现问题重重,之前写的也忘之脑后。又费了九牛二虎之力才把其缕顺。特写下来以做参考。
系统的结构图如下
1 主要涉及到与数据库打交道的实体类和 用于交互的 会话类。
通过依赖注入来注入数据库JNDI 连接资源 并且持久化实体管理器EntityManager :
@PersistenceContext(unitName="JEE_news_PU")protected EntityManager em;
2 利用JDK6的注释功能 可以很轻松的配置实体类与数据库的映射
package com.news.entitybean; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name="admin") public class Admin implements Serializable{ private int adminid; private String username; private String pwd; @Id() @GeneratedValue(strategy=GenerationType.AUTO) public int getAdminid() { return adminid; } public void setAdminid(int adminid) { this.adminid = adminid; } @Column(name="username",nullable=false) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Column(nullable=false) public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } }
3 前台有对应的类 包装了用到的参数 并且通过JNDI来查找会话类:
package com.news.backbean; import javax.naming.InitialContext; import com.news.sessionbean.AdminLocal; public class JSF_Loginbean { private String name; private String pwd; private String msg; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String checkLogin(){ try{ InitialContext ctx = new InitialContext(); AdminLocal adminLocal = (AdminLocal)ctx.lookup("AdminBean/local"); if(this.name.trim()==""){ this.msg = "the username is manadatory"; return null; }if(this.pwd.trim()==""){ this.msg="password is mandatory"; return null; } if(adminLocal.checkLogin(name, pwd)){ return "login_success"; }else{ this.msg="Login Failed"; return null; } }catch(Exception e){ this.msg="there is an innormal situation"; e.printStackTrace(); return null; } } }
会话类url注册 当web App容器跟EJB容器在同一个JVM环境下时候 用Local接口 不在的时候要用Remote Remote比Local更消耗系统性能
@Stateless @Remote(AdminRemote.class) @Local(AdminLocal.class) public class AdminBean implements AdminRemote,AdminLocal { 。。。。。。。
可以通过在faces-config.xml 配置managed-bean 可以控制前台包装类的显示名字 达到隐藏后台代码的目的
<managed-bean> <managed-bean-name>Loginbean</managed-bean-name> <managed-bean-class>com.news.backbean.JSF_Loginbean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>NewsListbean</managed-bean-name> <managed-bean-class>com.news.backbean.JSF_NewsListbean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>id</property-name> <value>#{param.id}</value> </managed-property> <managed-property> <property-name>currPage</property-name> <value>#{param.currPage}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>JSF_news</managed-bean-name> <managed-bean-class>com.news.backbean.JSF_AddNewsbean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
在faces-config.xml 中配置页面导航规则
<navigation-rule> <from-view-id>/pages/JSF_Login.xhtml</from-view-id> <navigation-case> <from-outcome>login_success</from-outcome> <to-view-id>/pages/newsIndex.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule>
4 加过滤器 为了实现session失效时重新登录功能 在web.xml里配置了过滤器和session的失效时间
<filter> <description>validate if has logined</description> <filter-name>Login Valid Filter</filter-name> <filter-class>com.news.backbean.Loginfilter</filter-class> </filter> <filter-mapping> <filter-name>Login Valid Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <session-config> <session-timeout>3</session-timeout> </session-config>