使用 AppFuse 快速构建 J2EE 应用
将其做如下修改: // initialize drop-downs
if (getAvailableRoles() == null) {
List roles = (List) getServletContext().getAttribute(Constants.AVAILABLE_ROLES);
for(int i=0;i<roles.size();i++){
LabelValue role=(LabelValue) roles.get(i);
role.setLabel(getText("rolelabel_"+role.getValue()));
}
setAvailableRoles(new RoleModel(roles));
}
并在 web\WEB-INF\classes\ApplicationResources_zh_CN.properties 中增加角色名称的定义: rolelabel_admin=系统管理员
rolelabel_user=普通用户
rolelabel_hr=人事管理
AppFuse 默认在用户管理界面上显示的角色的名称是表 role 中的名称,这样无论切换到何种语言,角色名称都是 “admin”、"user"、“hr” 等等,角色名称不能根据 Locale 用相应的语言显示。因此,本文将角色的名称用 Resource Bundle 文件定义,数据库中存储 “key” 值。修改后的效果见 图 10。
配置“安全策略”:在 web\WEB-INF\security.xml 的 bean "filterInvocationInterceptor" 声明中增加如下“黑体”的一行: <bean id="filterInvocationInterceptor"
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/clickstreams.jsp*=admin
/flushCache.*=admin
/passwordHint.html*=ROLE_ANONYMOUS,admin,user
/reload.*=admin
/signup.html*=ROLE_ANONYMOUS,admin,user
/users.html*=admin
/employees.html*=hr
/**/*.html*=admin,user
</value>
</property>
</bean>
“/employees.html*=hr” 的意思是:只有 hr 这个角色可以访问形如 “/employees.html*” 的 url。
将“员工信息维护”菜单关联到指定角色 hr:在 web\WEB-INF\menu-config.xml 中在 “EmployeeMenu” 的定义中增加 “roles='hr'”: <!--Employee-START-->
<Menu name="EmployeeMenu" title="employeeList.title" page="/employees.html" roles="hr"/>
<!--Employee-END-->
于是,“员工信息维护”的菜单入口只对属于“人事管理”角色的用户显示,对其他用户则隐藏。
分配角色 “hr” 给 tomcat:将“人事管理”角色分配给某一用户,例如 tomcat。则 tomcat能够看见并访问“员工信息维护”相关页面,而其他用户的界面上则没有“员工信息维护”这个菜单入口。并且,如果用户试图通过url访问employees.html的时候会看到如下页面:
图 14是 AppFuse 提供的默认“访问被拒绝”页面,你可以通过修改 web\403.jsp 把它定制成自己喜欢的页面。
事务控制
AppFuse 利用 Spring 的事务管理机制。Spring 可以以声明的方式,对方法进行事务控制,并且可以根据实际的需要,调整控制粒度。“声明方式”的好处在于:核心代码只需要关注业务逻辑,而将事务控制完全交由配置文件管理,一方面是核心代码简洁清晰,另一方面也便于进行集中配置管理。
事务控制一般是定义在 service 类的方法上的。AppFuse 的所有 service 类都声明在 src\service\applicationContext-service.xml 中,该文件中包含有一个 “txProxyTemplate” bean 的声明,它定义了基本事务策略。其它的 service 类从 “txProxyTemplate” 继承,并可以“重写”事务策略。例如,AppFuse 对 userManager 的声明如下:
<!-- Transaction template for Managers, from:
http://blog.exis.com/colin/archives/2004/07/31/concise-transaction-definitions-spring-11/ -->
|-- XML error: The previous line is longer than the max of 90 characters --|
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- Transaction declarations for business services. To apply a generic transaction proxy to
|-- XML error: The previous line is longer than the max of 90 characters --|
all managers, you might look into using the BeanNameAutoProxyCreator -->
<bean id="userManager" parent="txProxyTemplate">
<property name="target">
<bean class="org.appfuse.service.impl.UserManagerImpl">
<property name="userDao" ref="userDao"/>
</bean>
</property>
<!-- Override default transaction attributes b/c of UserExistsException -->
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED,-UserExistsException</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
<!-- This property is overriden in applicationContext-security.xml to add
method-level role security -->
<property name="preInterceptors">
<list>
<ref bean="userSecurityInterceptor"/>
</list>
</property>
</bean>
Spring 提供了大量的参数和选项使开发者能够灵活地管理事务。有关 Spring 使用方面的知识,请参阅 Spring 的文档。另外,《Spring in Action》也是一个不错的选择。
日志
AppFuse 集成了 Log4j 进行日志管理,log4j.properties 位于 web\WEB-INF\classes 目录下。AppFuse 已经在绝大多数基类(诸如,BasePage.java、BaseDaoHibernate.java 以及 BaseManager.java 等)中加入了如下用于输出日志的成员变量:
protected final Log log = LogFactory.getLog(getClass());
因此,开发者只需要在自己的代码中调用 log 的方法就可以了,例如:“log.debug("entered 'delete' method");”。
邮件
AppFuse 集成了 Spring 的发送邮件的功能。发送邮件需要用的参数,如主机、端口等信息在 web\WEB-INF\classes\mail.properties 中进行配置。和发送邮件相关的 bean 已经在 applicationContext-service.xml 中声明:mailEngine、mailSender、velocityEngine 以及 mailMessage。用户只需要在自己的类中 “注入” mainSender 的实例,就可以发送邮件了。具体使用方法,请参阅Spring的文档。
缓存
AppFuse 对缓存机制的支持源自 Hibernate 对缓存的支持。Hibernate 提供了对五种缓存机制的集成,AppFuse 默认提供了其中的两种:Ehcache 和 Oscache。开发者也可以根据需要自行添加和配置。Acegi 默认提供了对 Ehcache 支持的实现,所以 Ehcache 是较好的选择。ehcache.xml 和 oscache.properties 位于 web\WEB-INF\classes 中。
结束语
使用 AppFuse 创建 Web 应用,步骤非常简单,你只需要了解如何运行 Ant 就能够使用 AppFuse;使用 AppFuse 创建 Web 应用,非常快速,因为 AppFuse 已经帮我们完成大部分代码生成/集成/配置的工作;使用 AppFuse 创建 Web 应用,非常省力,因为 AppFuse 已经提供了很多“开箱即用”的功能。体验快速开发,从 AppFuse 开始。
关于作者
沈锐在 J2EE 项目开发方面有多年的经验,目前在 IBM CSDL 从事 IBM Workplace Dashboard Framework 产品的开发工作。他对 Java 的开源技术有着浓厚的兴趣,欢迎使用 shenrui@cn.ibm.com 与他交流。










文章评论
共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面