分享
 
 
 

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

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

一、Struts中引入ActionForm类的意义与缺陷

二、类反射的概念

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

四、结语

对于本文的评价

关于作者

Java 专区中还有:

教学

工具与产品

代码与组件

所有文章

实用技巧

邢波涛 (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把数据循环现实出来。代码通常都是这个样子:

<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本身就大量利用了类反射的机制。

三、如何应用类反射机制简化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中显示:

<table width="700" class="1" border="1" cellspacing="1" align="center">

<tr>

<td class="list" >用户ID</td>

<td class="list" >姓 名</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应用程序的开发。

关于作者

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

http://www.javajia.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有