一、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应用程序的开发。
二、类反射的概念
三、如何应用类反射机制简化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应用程序的开发。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



