1、AppFuse项目研究AppFuse项目研究-摘自AppFuse in china 第一部分:初始化1 初始化配置信息:Appfuse利用监听器,在应用程序启动时,初始化配置信息 监听器StartupListener功能:取得DAO.TYPE信息和角色信息,存入全局应用环境上下文,初始化Spring,使之可用。 应用:web.xml org.dudu.webapp.listener.StartupListener StartupListener 监听器:继承于Spring的 ContextLoaderListener和Sevelet的ServletContextListener,配置于Web.
2、xml中。 说明:凡是继承ServletContextListener接口的类,在web容器启动时调用其 contextInitialized方法进行初始化,当容器关闭时调用其contextDestroyed的方法进行销毁,我们可以利用这个特性初始化一些信息。 程序说明:(主要代码) public class StartupListener extends ContextLoaderListener implements ServletContextListener public void contextInitialized(ServletContextEvent event) /容器启动时
3、,自动调用contextInitialized函数。 /取得全局Application Scope 环境上下文 ServletContext context = event.getServletContext(); Map config = (HashMap) context.getAttribute(Constants.CONFIG); /将DAO_TYPE_HIBERNATE = hibernate写入ServletContext config.put(Constants.DAO_TYPE, daoType); context.setAttribute(Constants.CONFIG,
4、config); /调用setupContext(context)函数初始化Spring public static void setupContext(ServletContext context) /初始化Spring环境上下文,为getBean作准备,并且将ServletContext /交给Spring管理 ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context); / LookupManager为接口类,提供统一的调用接口 /通过Ico反射注入,查找loo
5、kupManager和Dao属性。(1) LookupManager mgr = (LookupManager) ctx.getBean(lookupManager); /取得角色信息,存入ServletContext scope中。 context.setAttribute(Constants.AVAILABLE_ROLES, mgr.getAllRoles(); (1)的说明:在配置文件中取值,动态加载LookupManagerImpl类 客户面对接口LookupManager,底层实现为LookupManagerImpl,Spring的一大 特点:自然的面向接口编程。LookupMana
6、gerImpl是POJO的管理类,真正的 数据操作委派给它的引用LookupDAO的具体实现类LookupDAOHibernateSpring配置文件 applicationContext-service.xml (2)(2)的说明:通过Ico动态加载对象属性LookupDAOHibernate Spring配置文件:applicationContext-hibernate.xml public class LookupManagerImpl extends BaseManager implements LookupManager private LookupDAO dao; public v
7、oid setLookupDAO(LookupDAO dao) /Spring动态注入dao引用,从配置文件中取得具体的lookupDAO,又一次的面向/接口编程 this.dao = dao; public List getAllRoles() / LookupManagerImpl将真正的数据操作委派个LookupDAOHibernate(3) List roles = dao.getRoles(); List list = new ArrayList(); Role role = null; for (int i = 0; i roles.size(); i+) role = (Role
8、) roles.get(i); list.add(new LabelValue(role.getName(), role.getName(); return list; 应用程序启动时,调用StartupListener初始化ServletCOntext环境变量、Spring环境变量和取得角色信息后,接着执行UserCounterListener监听器。 UserCounterListener功能:计算使用应用的用户个数和存储用户对象。应用启动使初始化用户数变量counter,并存入ServletContext,利用HttpSessionAttributeListener监听器每当Sessio
9、n中的属性值有变化时,修改ServletContext中的用户个数和,用户对象。 提供了一种全局跟踪用户信息的方法。 UserCounterListener监听器实现比较简单,主要时理解ServletContextListener和HttpSessionAttributeListener监听器的使用。 web.xml org.dudu.webapp.listener.UserCounterListener UserCounterListener监听器程序: UserCounterListener出来继承了ServletContextListener监听器接口外,还继承了 HttpSession
10、AttributeListener监听器接口。ServletContextListener监听器接口的作用已经在“初始化”前一部分作了介绍。 HttpSessionAttributeListener监听器介绍:HttpSessionAttributeListener监听 HttpSession中的属性的操作。当在Session增加一个属性时,激发 attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发 attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被
11、重新设置时,激 发attributeReplaced(HttpSessionBindingEvent se) 方法。 public class UserCounterListener implements ServletContextListener, HttpSessionAttributeListener public static final String COUNT_KEY = userCounter; public static final String USERS_KEY = userNames; private final transient Log log = LogFacto
12、ry.getLog(UserCounterListener.class); private transient ServletContext servletContext; private int counter; private Set users; public synchronized void contextInitialized(ServletContextEvent sce) servletContext = sce.getServletContext(); servletContext.setAttribute(COUNT_KEY), Integer.toString(count
13、er); public synchronized void contextDestroyed(ServletContextEvent event) servletContext = null; users = null; counter = 0; synchronized void incrementUserCounter() counter = Integer.parseInt(String) servletContext.getAttribute(COUNT_KEY); counter+; servletContext.setAttribute(COUNT_KEY, Integer.toS
14、tring(counter); if (log.isDebugEnabled() log.debug(User Count: + counter); synchronized void decrementUserCounter() int counter = Integer.parseInt(String) servletContext.getAttribute(COUNT_KEY); counter-; if (counter 0) counter = 0; servletContext.setAttribute(COUNT_KEY, Integer.toString(counter); i
15、f (log.isDebugEnabled() log.debug(User Count: + counter); synchronized void addUsername(Object user) users = (Set) servletContext.getAttribute(USERS_KEY); if (users = null) users = new HashSet(); if (log.isDebugEnabled() if (users.contains(user) log.debug(User already logged in, adding anyway.); use
16、rs.add(user); servletContext.setAttribute(USERS_KEY, users); incrementUserCounter(); synchronized void removeUsername(Object user) users = (Set) servletContext.getAttribute(USERS_KEY); if (users != null) users.remove(user); servletContext.setAttribute(USERS_KEY, users); decrementUserCounter(); publi
17、c void attributeAdded(HttpSessionBindingEvent event) if (event.getName().equals(Constants.USER_KEY) addUsername(event.getValue(); public void attributeRemoved(HttpSessionBindingEvent event) if (event.getName().equals(Constants.USER_KEY) removeUsername(event.getValue(); public void attributeReplaced(
18、HttpSessionBindingEvent event) / I dont really care if the user changes their information 图表 1 管理器类图 (3) 的说明:LookupDAOHibernate类图表 2 实体类图public class LookupDAOHibernate extends BaseDAOHibernate implements LookupDAO public List getRoles() if (log.isDebugEnabled() log.debug(retrieving all role names.)
19、; return getHibernateTemplate().find(from Role order by name); 集成Spring,StartupListener通过管理类LookupManagerImpl,委派LookupDAOHibernate类取得所有角色信息。然后将角色信息列表存入ServletContext环境上下文中。 StartupListener结束. 第二部分:权限认证Appfuse 的用户管理,它用到了容器管理的Form认证方式。 1.appfuse应用采用基于表单的登陆验证方式,登陆请求由login.jsp处理。 web.xml FORM /login.jsp
20、 /loginError.jsp 2通过静态应用,login.jsp将登陆请求委派给loginForm.js处理 login.jsp 3. 登陆请求由login servlet截获处理 WEB-INF/pages/loginFrom.jsp form method=post id=loginForm action= onsubmit=saveUsername(this);return validateForm(this) web.xml listenPort_http 8080 listenPort_https 8443 login Login Servlet org.appfuse.weba
21、pp.action.LoginServlet authURL j_security_check isSecure false encrypt-password true algorithm SHA 1 login /authorize/* 4处理登陆请求的LoginServlet,它出来初始化参数,生成处理过后的URL,然后在交由 LoginFilter处理 public void init() throws ServletException /取得初始化参数 authURL = getInitParameter(Constants.AUTH_URL); algorithm = getInit
22、Parameter(Constants.ENC_ALGORITHM); secure = Boolean.valueOf(getInitParameter(isSecure); encrypt = Boolean.valueOf(getInitParameter(encrypt-password); /存储安全认证参数 config.put(Constants.HTTP_PORT, httpPort); config.put(Constants.HTTPS_PORT, httpsPort); /class Constants中的定义 / public static final String S
23、ECURE_LOGIN = secureLogin; config.put(Constants.SECURE_LOGIN, secure); config.put(Constants.ENC_ALGORITHM, algorithm); config.put(Constants.ENCRYPT_PASSWORD, encrypt); ctx.setAttribute(Constants.CONFIG, config); 以下为appfuse表单认证设置 Web.xml中的设置 Unrestricted All users can view /passwordHint.html /signup.html http
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1