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

本文讲述了如何利用Java的反射的机制来简化Structs应用程序的开发。
 
在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把数据循环现实出来。代码通常都是这个样子:
<logic:present name="array " scope="request">  
<logic:iterate name=" array " id=" array "   type="com.bhsky.webis.Goods">    
<tr align="center">        
    <td class="table2">  
        <bean:write name=" array " property="goodsid"/>  
    </td>    
    <td class="table2">  
        <bean:write name=" array " property="goodsname"/>  
    </td>     
</tr>    
</logic:iterate>   
</logic:present>  

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




回页首


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




回页首


      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;  
       }
  }  

      /
      //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;
       }
  }  

     //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;
    }  

     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;
    }  

     <table width="700" class="1" border="1" cellspacing="1" align="center">
    <tr>
      <td class="list" >用户ID</td>
      <td class="list" >姓&#160&#160名</td>
    </tr>
    <logic:present name="userList" scope="request">
         <logic:iterate name="userList" id="userList"   type="com.bhsky.webis.system.UsersActionForm">
    <tr>
      <td class="cell1"  height="22"><bean:write name="userList"   property="usr_id"/></td>
      <td class="cell1"  height="22"><bean:write name="userList"   property="usr_name"/></td>
       </tr>
    </logic:iterate>
        </logic:present>
  </table>
  





回页首

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

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值