运用类反射机制简化Struts应用程序的开发

原创 2004年08月10日 08:53:00

邢波涛 (xbt@bhsky.com)

2003 年 11 月

本文讲述了如何利用Java的反射的机制来简化Structs应用程序的开发。

一、Struts中引入ActionForm类的意义与缺陷:
在Struts应用程序中,ActionForm是一个很重要的概念,它的主要功能就是为Action的操作提供与客户表单相映射的数据(如果在客户指定的情况下,还包括对数据进行校验)。Action根据业务逻辑的需要,对数据状态进行修改,在改变系统状态后,ActionForm则自动的回写新的数据状态并保持。程序员对JSP与ActionForm Bean的对应关系,通常感到很迷惑,JSP与ActionForm到底是1:1,还是N:1,对此,Struts本身对此并没有提出自己的观点。无论是一对一,还是多对一,Struts本身并不关心,它都能很好得工作。Struts在它的开发文档中指出,对于较小规模的开发,开发人员可以根据自己的需要,每个模块只写一个ActionForm Bean,甚至整个应用程序只写一个ActionForm Bean.当然,Struts也不反对每个ActionForm Bean只对应一个JSP,他们之间的对应关系,由开发人员自己决定。

在我看来,正如Entity EJB对J2EE的重大贡献一样,Entity EJB使得程序员对二维关系数据库的存取对象化了,程序员可以使用Set 或者Get等面向对象的方法来操纵关系数据库的数据,而ActionForm也使得程序员对网页的数据存取奇迹般的对象化了,程序员同样也可以使用Set 或者Get等面向对象的方法存取网页上的数据,这是一个开发模式方式上的重大转变。基于此,我个人认为ActionForm与JSP即VIEW层的关系最好是一对一的关系,这样,在理解上会更清晰一些。但是,这样也会带来一个很现实的问题,在一个应用程序中,也许有非常多得JSP页面,如果每个ActionForm 都只对应一个JSP页面,那么系统的Java代码就会急剧膨胀起来,而且,每个ActionForm都是只有很简单的Set或者Get方法存取数据,那么,如何简化Struts应用程序的开发呢?

在Struts1.1 中,Struts引入了DynaActionForm和Dyna Bean,试图解决这个问题,在我看来,DynaActionForm的引入,破坏了对网页存取对象化的概念,使开发人员重新回到了使用HashTable、Map、Collection、ArrayList等集合对象来实现对数据进行存取的老路上来。虽然应用程序的灵活性大大增加了,但是代码的可读性也大大降低了,开发人员之间的交流难度也增加了。

在传统的应用程序对ActionForm Bean的访问中,我们通常都写成如下的形式:


Connection conn=DriverManager.getConnection("JDBC URL ");
      sql=" select *  from some tables ";
PreparedStatement stmt = conn.prepareStatement(sql);
      ResultSet rs = stmt.executeQuery();
ArrayList array=new ArrayList();
while (rs.next()) {
   AActionForm actionForm =new AActionForm ();
   actionForm.setId(rs.getString("Id"));
   actionForm.setName(rs.getString("Name"));           
   array.add(actionForm);
}
   

在Action 的Execute方法中,我们 把这个集合用request.setAttribute("array", array)存储起来,然后在JSP页面中,我们用iterate Tag把数据循环现实出来。代码通常都是这个样子:


<?xml:namespace prefix = logic />
<?xml:namespace prefix = bean />

在Struts中,对数据的访问和显示的写法通常都是很固定的,在VIEW层,我们是没有办法简化自己的代码的,在Action层,其写法通常也很固定,只是做一个页面的跳转,商业逻辑和对数据得访问,通常都是放在JavaBean中。那么,在此,我提出一种运用类反射的机制,使应用程序对ActionForm Bean的赋值自动化,即应用程序通过一个简单的接口,使用一个通用的方法,就可以完成对ActionForm Bean的赋值,而不必在每个使用ActionFormBean的地方,都把数据库中的值手动赋值给ActionForm Bean,然后再在JSP页面中显示出来。虽然它不能减少ActionForm Bean的数量,但是,它至少使应用程序对ActionForm Bean的赋值自动化了,从而减少了程序出错概率,提高了程软件开发效率。

二、类反射的概念:
关于类反射的概念,在此我就不详细介绍了,它不是本文的重点,IBM developerWorks网站上有大量介绍类反射概念的文章,大家可以找出来参考一下。其实,Struts本身就大量利用了类反射的机制。

三、如何应用类反射机制简化Struts应用程序的开发:

1、 先定义Action FormBean:


    package com.bhsky.webis.system;
import org.apache.struts.action.*;
import javax.servlet.http.*;
    
public class UsersActionForm extends ActionForm {
private String usr_id;
private String usr_name;
public void setUsr_id(String usr_id) {
    this.usr_id = usr_id;
}
public String getUsr_id() {
    return usr_id;
}
public String getUsr_memo() {
    return usr_memo;
}
public void setUsr_name(String usr_name) {
    this.usr_name = usr_name;
}
}

2、 编写通用的为ActionFormBean赋值的方法:


    /////////////////////////////////////////////////////////////////////////////
    //Function: 完成ResultSet对象向ArrayList对象为集合的对象的转化
    //Para:sql,指定的查询Sql
   //Para:className,Sql相对应得JavaBean/FormBean类的名字
   //Return:以类className为一条记录的结果集,完成ResultSet对象向ArrayList对象为集//合的className对象的转化
  //////////////////////////////////////////////////////////////////////////////
  public ArrayList Select(String sql,String className){
    ArrayList paraList=new ArrayList();
    try{
      if (conn == null){
        Connection();
      }
      PreparedStatement stmt = conn.prepareStatement(sql);
      ResultSet rs = stmt.executeQuery();
      String recordValue="";
      Object c1=null;
      paraList=new ArrayList();
      ResultSetMetaData rsmd = rs.getMetaData();
      int columnCount = rsmd.getColumnCount();
      while (rs.next()){
          c1=Class.forName(className).newInstance();
          for (int i=1; i<=columnCount; i++) {
            if(rs.getString(rsmd.getColumnName(i))!=null){
              recordValue=rs.getString(rsmd.getColumnName(i));
            }else{
              recordValue="";
            }
Method 
m=c1.getClass().getMethod(getSetMethodName(rsmd.getColumnName(i)),
new Class[]{recordValue.getClass()});
            m.invoke (c1, new Object[]{recordValue});
          }
          paraList.add(c1);
      }
    }catch(SQLException ex){
      
}catch(ClassNotFoundException e){

}catch(NoSuchMethodException e) {

}catch(InvocationTargetException e){

}catch (IllegalAccessException e){

}catch(InstantiationException e){

} finaly{
        closeConnection();
return paraList;
}
  }

3、 在JavaBean封装的商业逻辑中调用Select 方法,然后在JSP页面上显示出来:


   //Function:取得用户列表
  //Para:
  //Return:返回用户列表
  /////////////////////////////////////////////////////////////////////////////
  public ArrayList getUsers(){
      ArrayList ret=null;
      DatabaseManage db=new DatabaseManage();
      String sql=" select usr_id,usr_name "
          +" from users " ;
      ret=db.Select(sql," com.bhsky. webis.system.UsersActionForm");
      return ret;
  }

4、 在Action的execute方法中调用getUsers()方法:


   public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, 
     HttpServletRequest request, HttpServletResponse httpServletResponse) 
   {
    /**@todo: complete the business logic here, this is just a skeleton.*/
    UsersActionForm uaf=(UsersActionForm)actionForm;
    SystemService ubb=new SystemService();
    ArrayList userList=ubb.getUsers();
    request.setAttribute("userList",userList);
    ActionForward actionForward=actionMapping.findForward(url);
    return actionForward;
  }

5、 在JSP中显示:


   
用户ID姓  名

四、结语:
我们通过运用类反射机制,在一个Struts应用开发中,完成了一个通用查询方法的实现。它使得程序员摆脱了在每个应用程序中都要编写枯燥的set、get等方法来访问ActionForm Bean,从而简化了Struts应用程序的开发。

关于作者
邢波涛 , 您可以通过 xbt@bhsky.com 与他联系。

Java反射机制与应用

JAVA反射机制     JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能...
  • xiaoxian8023
  • xiaoxian8023
  • 2013年06月30日 20:45
  • 9329

Java反射机制与动态代理(二)

导读: 1. 代理模式 2. 静态代理 3. 动态代理 4. 小结 一、代理模式代理模式所涉及的角色有: - 抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何...
  • qq_29342837
  • qq_29342837
  • 2017年11月24日 00:06
  • 35

JAVA反射机制的应用场景(注:菜鸟勿喷~~)

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和...
  • sun5769675
  • sun5769675
  • 2015年09月28日 17:33
  • 2115

常用类和反射机制

1 常用类 应用程序不能创建自己的Runtime实例,但是可以通过Runtime类的静态方法getRuntime()获取与之关联的Runtime对象:Runtime rt=Runtime.getRu...
  • qq_31424991
  • qq_31424991
  • 2015年10月18日 23:02
  • 346

spring的ioc原理(java反射机制)

为什么要有ioc这个概念,其实自己以前一直不是很理解,后来随着自己经验稍微多了一些,认识到,在一些系统中,通过这种依赖注入的方式确实可以让代码之间的耦合更弱一些,可以更好管理对象之间的关系。。。 其...
  • fjs_cloud
  • fjs_cloud
  • 2013年09月27日 16:33
  • 2372

利用反射机制创建新类的两种方式及比较

【0】README0.1) 本文描述+源代码均 转自 http://blog.csdn.net/fenglibing/article/details/4531033 , 旨在深入理解 如何利用反射机制...
  • PacosonSWJTU
  • PacosonSWJTU
  • 2015年11月17日 13:38
  • 640

跟着辛星深入探讨一下PHP的反射机制

早在之前学习Java的时候,清楚的记得是学完了多线程之后学习的反射,现在在PHP中当然也有反射机制,如果童鞋你还不明白,那就需要搞明白奥,毕竟反射的功能还是蛮强大的,学习它还是很具有现实意义的。 反射...
  • xinguimeng
  • xinguimeng
  • 2014年07月24日 02:54
  • 1450

Qt类反射机制

前言 如何通过类名动态的创建对象(类反射),对于Java开发者来说一点也不陌生,当然Qt也提供了一个元对象系统(The Meta-Object System),通过这个系统我们可以动态的在运行时获...
  • Kenier
  • Kenier
  • 2017年03月14日 13:03
  • 1297

对于JAVA反射机制和CLASS类的个人理解

上周上课老师点我起来回答问题,问了一下JAVA反射机制,我本来对JAVA用得不多,加上有一段时间没有看过了,所以并没有能够答出来,之后就想要好好理解理解,加上老师布置作业让弄懂JAVA反射和Class...
  • qq_32377239
  • qq_32377239
  • 2016年10月16日 19:41
  • 327

利用Java的反射与代理机制实现AOP

在上一篇文章中,我们讲述了利用Java的反射机制中实现Spring中的IOC,在本文中,我们将更进一步,讲述用Java的反射和动态代理机制来实现Spring的AOP。 一.AOP概述        A...
  • xybelieve1990
  • xybelieve1990
  • 2016年01月19日 17:10
  • 980
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:运用类反射机制简化Struts应用程序的开发
举报原因:
原因补充:

(最多只允许输入30个字)