使用 AppFuse 快速构建 J2EE 应用

时间:2007-02-05 16:05:42   来源:  作者:沈锐  点击:次  出处:技术无忧
关键字:AppFuse 增删查改 事务控制 Windows

将其做如下修改: // 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. “访问被拒绝”页面
 bad63341409f029bafd44ffdfce8306d.gif

图 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 开始。

关于作者

 efbf185405002fc8488addd4e5dd8bb7.jpg

  沈锐在 J2EE 项目开发方面有多年的经验,目前在 IBM CSDL 从事 IBM Workplace Dashboard Framework 产品的开发工作。他对 Java 的开源技术有着浓厚的兴趣,欢迎使用 shenrui@cn.ibm.com 与他交流。
 

讨论 http://bbs.pc51.net


 5/5   |‹ ‹‹ 3 4 5

文章评论

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

特别推荐