EJB方法调用框架

  作者:板桥banq

上页

7.4  框架的使用和调试

前面章节进行了EJB方法调用框架的设计和实现,该框架系统能够动态适应不同的应用情况。在以后章节中,凡是对EJB的调用,都将使用本框架实现。
下面将分别从肥客户端和瘦客户端两个应用角度,简单地讨论和测试该框架系统的使用。

7.4.1  配置

其实在前面框架系统的详细设计中已经有相关客户端使用介绍。这里以第6章介绍的用户安全管理系统为例,看看如何在这个系统中使用EJB方法调用框架。
首先激活框架系统的远程访问,在web.xml加入:
<servlet>
    <servlet-name>EJBInvokerServlet</servlet-name>
    <display-name>接受远程客户端访问</display-name>
    <servlet-class>com.jdon.bussinessproxy.remote.http.InvokerServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>EJBInvokerServlet</servlet-name>
    <url-pattern>/auth/EJBInvokerServlet</url-pattern>
</servlet-mapping>
然后激活容器基于HTTP的基本验证,配置web.xml:
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>SecurityRealm</realm-name>
</login-config>
在web.xml中定义访问权限如下:
<security-constraint>
    <display-name>User protected</display-name>
    <web-resource-collection>
      <web-resource-name>Collection1</web-resource-name>
      <url-pattern>/auth/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>User</role-name>
    </auth-constraint>
    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
</security-constraint>
这样,访问/auth /EJBInvokerServlet将得到授权保护。下面在web.xml中分别配置该系统的角色和JNDI配置。
  <security-role>
    <role-name>Admin</role-name>
  </security-role>
  <security-role>
    <role-name>User</role-name>
  </security-role>
  <ejb-local-ref>
    <ejb-ref-name>ejb/EJBContollerLocal</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local-home>com.jdon.security.auth.ejb.SecurityFacadeLocalHome</local-home>
    <local>com.jdon.security.auth.ejb.SecurityFacadeLocal</local>
    <ejb-link>SecurityFacade</ejb-link>
  </ejb-local-ref>
在jboss-web.xml配置中使用容器安全机制:
<jboss-web>
    <security-domain>java:/jaas/SecurityRealm</security-domain>
</jboss-web>
然后在JBoss的login-config.xml中配置SecurityRealm,配置EJB层安全访问机制。这些具体细节可参考第6章。
下面分别以瘦客户端和肥客户端应用为例。

7.4.2  浏览器/服务器架构下的应用

以用户注册资料查询为例,当用户注册后,通过调用http://localhost:8080/Auth Test/auth/editSignUpAction.do,将会显示用户数据库中保存的用户注册资料,这一功能在第6章是通过接口框架UserService实现的,这里将更换为使用EJB方法调用框架来实现,代码如下:
public class EditSignUpAction extends Action {
  public final static String module = EditSignUpAction.class.getName();
  public ActionForward execute(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse httpServletResponse) throws
      Exception {

    String action = FormBeanUtil.EDIT_STR;
    int actionInt = FormBeanUtil.actionTransfer(action);
    if (form == null) {
      form = new UserForm();
      FormBeanUtil.save(form, mapping, request);
    }
    UserForm userForm = (UserForm) form;
    getSignUpForm(actionInt, userForm, request);
    userForm.setAction(action);
    return (mapping.findForward("success"));
  }

  //  更换的本方法内容
  private void getSignUpForm(int actionInt, UserForm userForm,
                             HttpServletRequest request) {

    try {
      //获得ServiceServerFactory工厂实例
      ServiceServerFactory serviceFactory = ServiceServerFactory.getInstance();
      //获得SecurityFacadeLocal代理实例
      SecurityFacadeLocal securityFacadeLocal = (SecurityFacadeLocal)
          serviceFactory.getService(FrameworkServices.SecurityFacade, request);
      //直接执行SecurityFacadeLocal方法
      User user = securityFacadeLocal.getUser();

      Debug.logVerbose(" user name is" + user.getName() + " userId is" +
                       user.getUserId(), module);
      PropertyUtils.copyProperties(userForm, user);
      userForm.setPassword2(user.getPassword());
    } catch (Exception e) {
      Debug.logError("getSignUpForm error" + e, module);
    }
  }
}
配置相应的struts-config.xml如下:
<action attribute="userForm" type="com.jdon.security.web.EditSignUpAction"
validate="false" scope="request" path="/auth/editSignUpAction">
      <forward name="success" path="/account/signup.jsp" />
</action>
在后面章节“网上商店系统”中,将主要使用本框架实现EJB的调用,详细内容可见该章节。

 

7.4.3  肥客户端/服务器架构下的应用

肥客户端是一个独立运行的系统,建立测试客户端如下:
public class RemoteClientTest {
  public static void main(String[] args) {
    try {
     System.out.println(" enter test.");
      //获得ServiceClientFactory工厂实例
      ServiceClientFactory serviceFactory = ServiceClientFactory.getInstance();
  
   System.out.println(" prepare to login ..");
      //以用户名banq 密码9999登录
      //这个用户名和密码是保存在服务器端的数据库user中
      String result = (String)serviceFactory.login("banq", "9999");
      System.out.println(" login ok , result =" + result);

      //获得EJB代理实例
      SecurityFacadeLocal securityFacadeLocal =
          (SecurityFacadeLocal) serviceFactory.getService(FrameworkServices.
          SecurityFacade);
      //调用方法
      User user = securityFacadeLocal.getUser();
      System.out.println(" user name=" + user.getName());
      System.out.println(" user email =" + user.getEmail());

    } catch (AuthException ae) {
      System.err.println(" login failure");
      System.err.println(ae);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
访问的Http服务器网址是http://localhost:8080/AuthTest/auth/EJBInvokerServlet
运行后的结果如下:
enter test
prepare to login ...
login ok , result =<html><head><title>InvokerServlet</title></head><body> banq Welcome to login in !!</body></html>
user name=banq
user email =banq@163.net
如果更换成数据库user中不存在的用户名和密码,再次运行本测试程序,会抛出AuthException异常。
通过以上测试,证明EJB方法调用框架能够适应运行在多个应用场合,使用方便,EJB代码调用简洁,是一个可以反复使用的良好的框架系统。

7.5  小结

本章主要介绍了一种EJB调用框架,通过Java的方法(Method)反射机制直接调用EJB方法。这种框架的最大优点是隔离了Web层和EJB层,实现了两者的完全解耦,简化了EJB服务的调用结构。
在中大型系统中,由于系统功能的复杂,导致实现这些功能的EJB数量剧增。同时,一个功能的完全实现常常是贯穿于Web层和EJB层,客户端通过Web层调用EJB方式可能有多种形式。最通常的情况是,Web层调用一个EJB Facade类,通过这个Facade再调用其他EJB,这种模式在EJB数量巨大的情况下,会导致系统调用混乱。有时除了开发者本人掌握调用的来龙去脉外,其他人很难了解其中的调用路径,犹如走入迷宫,这种情况必然导致系统的可维护性和可拓展性降低。
图7-6显示了使用本框架前后的调用效果:
1
图7-6  使用EJB方法调用框架的前后效果
在未使用本框架的情况下,客户端调用EJB的规则可能是混乱的、或者没有次序的。但是使用了本框架后,每个EJB成为一种Service,单独并列地对外提供服务,每个客户端都是直接调用EJB中的方法功能,不再通过中间者传递或转调用。理顺了EJB的调用层次,使之更加简单清晰,这种优点在复杂的大型系统中尤为重要。
本框架的远程调用部分虽然非常类似Web Services的JAX-RPC,但是由于没有引入XML,而是通过HTTP协议直接传输对象的Byte字节,消除了XML和Java对象之间转换的性能损耗。
由于无须掌握其他类似SOAP、JAXM或JAXR等更多概念,本框架的远程调用部分使用非常方便,适合C/S多层结构的快速开发。
当然,为了支持更多的客户端类型和远程调用类型,可以使用Web Service技术扩充或提升本框架的远程调用部分。
本框架能够应用在很多J2EE项目中,如CRM、OA、电子商务或者无线应用等项目系统。

 

 

首页