在JavaBean 中实现数据库操作的一点个人见解

在JavaBean 中实现数据库操作的一点个人见解 作者:小草/JAVA特刊 JAVA作为较新编程语言,是公认的最具前途的一种,她的网络优势以及其平台无关性,使得建立分布式系统更简单易行,更由于她的出现,使Internet的作用从通信工具扩展到能够运行成熟应用系统的网络。那么是应用系统,不可避免的也许就是数据库。 使用JAVA编制Server端应用程序(B/S),与传统的C/S应用程序在连接数据库方面有着本质的区别.在传统的C/S应用程序中,用户在使用应用程序时是一个长连接,只有在用户退出在程序时,才断开这个连接;而B/S则不一样,它是基于Tcp/IP的一种无状态连接,用户在发一个请求后,Server响应并分配一个连接,当请求结束后,该连接随即失效,Server将根本不知道该连接是那个用户请求的,同样,用户在发下一个请求之前,也将根本不知道要连向哪个Server.正是由于这种区别,使得在程序的编制方面,两种系统有着不一样的原则,否则将可能出现完全不一样的效果! 下面,本人抛砖引玉,谈谈自己在这方面的一点点心得。 在进行数据库操作时,一般在Bean 中不要进行直接的数据库连接(包括引用其他方法来建立连接,即不要无中生有,只使用已存在的Connection 或者 Statement),更不应在构造函数中即生成一个连接,因为一个Bean有可能被多个应用程序引用,同样一个应用程序有可能引用多个Bean ,这样如果一个Bean 如上所述在构造函数中即生成一个连接,那么一个应用程序从开始到结束可能生成许多连接; 同样,在Bean 中的某个方法中也不应该直接建立连接; 那么应该如何在Bean 中进行数据库操作呢? 如果进行数据库查询,即使用Select 语句,可以在方法中直接使用一个Statement 参数。 如:

public ResultSet getRS(Statement stmt,String sqltxt)

{

ResultSet rs=null;

Try

{

    rs=stmt.executeQuery(sqltxt);

}

catch(SQLException e){}

return rs;

}

如果查询语句中有多个Select且嵌套,如 
public String getS(Statement stmt,String sqltxt,String sqltxt1)

{

ResultSet rs=null;

Try

{

rs=stmt.executeQuery(sqltxt);

while(rs.next())

{

ResultSet rs1=stmt.executeQuery(sqltxt1)

If(rs1.next())

{

String s1=rs.getString(1);

String s2=rs1.getString(1);

..............

}

}

}

catch(SQLException e){}

return rs;

}

如果如上所述,两个Select 语句使用一个Statment ,那么将出错或者所得出的结果不正确。解决的方法,可以使用增加Statement 参数,以实现上述查询功能,但是使用增加Statement 参数的方法毕竟是有局限的,如果嵌套层数增加,Statement 参数也许也得跟着增加,这样对于程序的可扩张性是不利的,因为参数数量的不确定(即接口不确定),那么面向对象就没有意义了。 那么另外一种方法,就是直接传入Connection ,但是,如1 所述,不应在方法中直接引入,而是通过构造函数,或者单独一个方法来引入Connection(将该Connection 赋值给Bean中一个Connection 公共变量)。因为一般的应用程序,从开始到结束,不出意外一个Connection 就能完成所有工作,所以无需多次引入。 如:


import java.sql.*;

public class ClassName

{

Connection con1=null;

public ClassName()

{

}

public ClassName(Connection conn)

{

    con1=conn;

}

public void getConn(Connection conn)

{

    con1=conn;

}

public String getS(String sqltxt)

{

String s1=null;

try

{

    ......  

}

catch(SQLException e){}

return s1;

}

.......

}
如果SQL语句是对数据库的增、删、改等,那么可以引入一个Statement 来完成工作,因为不存在ResultSet 的问题,所有的操作都可以用一个Statement 来完成,同上(引用Connection 方法一样)可以使用构造函数或者单独一个方法来引入Statement (建议使用后一种,使用单独一个方法来引入,这样可以避免Connection 和Statement 都要引入的冲突)。 此外,对于数据库的增、删、改也可以,将所有的增、删、改的SQL语句放在一个Batch(批处理),最后执行这个Batch,方法如下:

import java.sql.*;

public class ClassName

{

Statement stmt=null;

public ClassName()

{

}

public void getStatement(Statement stmt_out)

{

    stmt=stmt_out;

}

public String update(...)

{

    String sqltxt="update tableName set....."

}

public String insert(...)

{

    String sqltxt="insert into tableName (....)values(....)"

}

public String del(...)

{

    String sqltxt="delete from tableName where ....."

}

public String mainPub()

{

stmt.addBatch(update(...));

stmt.addBatch(insert(...));

stmt.addBatch(del(...));

.....

stmt.executeBatch();

}

}
最后,再重申一遍,这只是本人的一点体会,如有不妥望不吝啬教! -------------------------------------------------------------------------------- <淘宝热门商品:
 

16.00 元  

减肥极品魔芋胶

 

2.35 元  

露连泉百货超级市场

阿尔卑斯喜缘喜糖 全市最低价


来源:程序员网

小小豆叮

在JavaBean 中实现数据库操作的一点个人见解

在JavaBean 中实现数据库操作的一点个人见解 作者:小草/JAVA特刊 JAVA作为较新编程语言,是公认的最具前途的一种,她的网络优势以及其平台无关性,使得建立分布式系统更简单易行,更由于她的出现,使Internet的作用从通信工具扩展到能够运行成熟应用系统的网络。那么是应用系统,不可避免的也许就是数据库。 使用JAVA编制Server端应用程序(B/S),与传统的C/S应用程序在连接数据库方面有着本质的区别.在传统的C/S应用程序中,用户在使用应用程序时是一个长连接,只有在用户退出在程序时,才断开这个连接;而B/S则不一样,它是基于Tcp/IP的一种无状态连接,用户在发一个请求后,Server响应并分配一个连接,当请求结束后,该连接随即失效,Server将根本不知道该连接是那个用户请求的,同样,用户在发下一个请求之前,也将根本不知道要连向哪个Server.正是由于这种区别,使得在程序的编制方面,两种系统有着不一样的原则,否则将可能出现完全不一样的效果! 下面,本人抛砖引玉,谈谈自己在这方面的一点点心得。 在进行数据库操作时,一般在Bean 中不要进行直接的数据库连接(包括引用其他方法来建立连接,即不要无中生有,只使用已存在的Connection 或者 Statement),更不应在构造函数中即生成一个连接,因为一个Bean有可能被多个应用程序引用,同样一个应用程序有可能引用多个Bean ,这样如果一个Bean 如上所述在构造函数中即生成一个连接,那么一个应用程序从开始到结束可能生成许多连接; 同样,在Bean 中的某个方法中也不应该直接建立连接; 那么应该如何在Bean 中进行数据库操作呢? 如果进行数据库查询,即使用Select 语句,可以在方法中直接使用一个Statement 参数。 如:

public ResultSet getRS(Statement stmt,String sqltxt)

{

ResultSet rs=null;

Try

{

    rs=stmt.executeQuery(sqltxt);

}

catch(SQLException e){}

return rs;

}

如果查询语句中有多个Select且嵌套,如 
public String getS(Statement stmt,String sqltxt,String sqltxt1)

{

ResultSet rs=null;

Try

{

rs=stmt.executeQuery(sqltxt);

while(rs.next())

{

ResultSet rs1=stmt.executeQuery(sqltxt1)

If(rs1.next())

{

String s1=rs.getString(1);

String s2=rs1.getString(1);

..............

}

}

}

catch(SQLException e){}

return rs;

}

如果如上所述,两个Select 语句使用一个Statment ,那么将出错或者所得出的结果不正确。解决的方法,可以使用增加Statement 参数,以实现上述查询功能,但是使用增加Statement 参数的方法毕竟是有局限的,如果嵌套层数增加,Statement 参数也许也得跟着增加,这样对于程序的可扩张性是不利的,因为参数数量的不确定(即接口不确定),那么面向对象就没有意义了。 那么另外一种方法,就是直接传入Connection ,但是,如1 所述,不应在方法中直接引入,而是通过构造函数,或者单独一个方法来引入Connection(将该Connection 赋值给Bean中一个Connection 公共变量)。因为一般的应用程序,从开始到结束,不出意外一个Connection 就能完成所有工作,所以无需多次引入。 如:


import java.sql.*;

public class ClassName

{

Connection con1=null;

public ClassName()

{

}

public ClassName(Connection conn)

{

    con1=conn;

}

public void getConn(Connection conn)

{

    con1=conn;

}

public String getS(String sqltxt)

{

String s1=null;

try

{

    ......  

}

catch(SQLException e){}

return s1;

}

.......

}
如果SQL语句是对数据库的增、删、改等,那么可以引入一个Statement 来完成工作,因为不存在ResultSet 的问题,所有的操作都可以用一个Statement 来完成,同上(引用Connection 方法一样)可以使用构造函数或者单独一个方法来引入Statement (建议使用后一种,使用单独一个方法来引入,这样可以避免Connection 和Statement 都要引入的冲突)。 此外,对于数据库的增、删、改也可以,将所有的增、删、改的SQL语句放在一个Batch(批处理),最后执行这个Batch,方法如下:

import java.sql.*;

public class ClassName

{

Statement stmt=null;

public ClassName()

{

}

public void getStatement(Statement stmt_out)

{

    stmt=stmt_out;

}

public String update(...)

{

    String sqltxt="update tableName set....."

}

public String insert(...)

{

    String sqltxt="insert into tableName (....)values(....)"

}

public String del(...)

{

    String sqltxt="delete from tableName where ....."

}

public String mainPub()

{

stmt.addBatch(update(...));

stmt.addBatch(insert(...));

stmt.addBatch(del(...));

.....

stmt.executeBatch();

}

}
最后,再重申一遍,这只是本人的一点体会,如有不妥望不吝啬教! -------------------------------------------------------------------------------- <淘宝热门商品:
 

¥:28.00 

冲三皇冠疯抢啦 亲亲baby快乐驿站,宝宝用品童鞋童帽童装

*皇冠特色*纯手工,可爱特别的老虎护耳帽宝宝帽子童帽,46-48cm

 

205.00 元  

东菱小熊贝尔莱德艾美特(面包机酸奶机挂烫机电暖器礼品小家电)

双皇冠,产地代理『艾美特暖风机HP2009』2000W功率,浴居两用


来源:程序员网

小小豆叮

如何在Jsp中使用JDBC来联结MySql

在以前的文章中,豆腐曾经讲过一种用JDBC-ODBC Bridge 来连接数据库的文章 一个 连接数据库的 javaBean(可在 Jsp 中调用),由于这样连接数据库的效率是 很低的,所以大家其实实际在使用的时候都是用的JDBC,现在我就给大家来说说如何在Win2K下使用JDBC 来连接 MySql的文章 首先是mySQL的JDBC驱动程序的下载,下载地址在:http://download.sourceforge.net/pub/mirrors/mysql/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz 下载结束后,把这个zip文件随意解压到任意的目录,我们假设目录是:d:jdbc,ok!下面我们来设置ClassPAth 以保证我们的WebServer能够访问到这个驱动程序 设置方法如下: 1.我的电脑->系统->设置环境变量 如果已经有ClassPAth 就编辑,否则增加一个ClassPAth 2.设置ClassPAth的值:d:jdbcmm.mysql.jdbc-1.2cmysql_comp.jar 3.重新启动 服务器 等到启动完成后,即可 JDBC 设置完成以后,很多的人可能还不是很清楚我们的JDBC 是否真正的安装成功了,我们就用一个JDBC联结MySQl的程序来检测一下 看我们是否是真正的安装成功了 代码如下: < % @ page contentType="text/html;charset=gb2312" % > < % java.sql.Connection conn; java.lang.String strConn; Class.forName("org.gjt.mm.mysql.Driver").newInstance(); sqlConn= java.sql.DriverManager.getConnection("jdbc:mysql://localhost/test","root",""); % > 代码虽然简单,但是却已经完成了我们测试MySql JDBC 安装的成功与否。 本篇文章的完成,多亏了 东方一蛇 的大力帮助,在此 表示感谢。 <淘宝热门商品:
 

 

徽商联盟】皇冠信誉店 联盟化妆品の屋

 

6.80 元  

北欧橱窗

三冠 三角形强力吸墙角架/置物架/杂物架 承重3公斤 不伤墙面0.14


来源:程序员网

小小豆叮

DOM文档操作和XML文件互相转换的java实现

简介:该文简要描述了DOM的概念和内部逻辑结构,给出了DOM文档操作和XML文件互相转换的java实现过程。 1. DOM简介 目前,W3C已于2000年11月13日推出了规范DOM level 2。文档对象模型(DOM)是HTML和XML文档的编程接口规范,它与平台和语言是无关的,因而可以用各种语言在各种平台上实现。该模型定义了THML和XML文件在内存中的逻辑结构(即为文档),提供了访问、存取THML和XML文件的方法。利用DOM规范,可以实现DOM 文档和XML之间的相互转换,遍历、操作相应DOM文档的内容。可以说,要自由的操纵XML文件,就要用到DOM规范。 2. DOM内部逻辑结构 DOM文档中的逻辑结构可以用节点树的形式进行表述。通过对XML文件的解析处理,XML文件中的元素便转化为DOM文档中的节点对象。DOM的文档节点有Document、Element、Comment、Type等等节点类型,其中每一个DOM文档必须有一个Document节点,并且为节点树的根节点。它可以有子节点,或者叶子节点如Text节点、Comment节点等。任何的格式良好的XML文件中的每一个元素均有DOM文档中的一个节点类型与之对应。利用DOM接口将XML文件转化成DOM文档后,我们就可以自由的处理XML文件了。 3. java中的DOM接口 DOM规范提供的API的规范,目前Sun公司推出的jdk1.4测试版中的java API遵循了 DOM level 2 Core推荐接口的语义说明,提供了相应的java语言的实现。 在org.xml.dom中,jkd1.4提供了Document、DocumentType、Node、NodeList、Element、Text等接口,这些接口均是访问DOM文档所必须的。我们可以利用这些接口创建、遍历、修改DOM文档。 在javax.xml.parsers中,jkd1.4提供的DoumentBuilder和DocumentBuilderFactory组合可以对XML文件进行解析,转换成DOM文档。 在javax.xml.transform.dom和javax.xml.transform.stream中,jdk1.4提供了DOMSource类和StreamSource类,可以用来将更新后的DOM文档写入生成的XML文件中。 4. 例程 4.1 将XML文件转化成DOM文档 这个过程是获得一个XML文件解析器,解析XML文件转化成DOM文档的过程。 Jdk1.4中,Document接口描述了对应于整个XML文件的文档树,提供了对文档数据的访问,是该步骤的目标。Document接口可以从类DocumentBuilder中获取,该类包含了从XML文档获得DOM文档实例的API。XML的解析器可以从类DocumentBuilderFactory中获取。在jdk1.4中,XML文件转化成DOM文档可以有如下代码实现: //获得一个XML文件的解析器 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //解析XML文件生成DOM文档的接口类,以便访问DOM。 DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(FileName) ); 4.2 遍历DOM文档 获得接口类document实例后,可以对DOM的文档树进行访问。要遍历DOM文档,首先要获得Root元素。然后获得Root元素的子节点列表。这里通过递归的方法实现遍历的目的。


//获得Root元素
Element element = document.getDocumentElement();
//获得Root元素的子节点列表
nodelist = element.getChildNodes();
//用递归方法实现DOM文档的遍历
GetElement(nodelist);
其中GetElement方法实现如下:
public void GetElement(NodeList nodelist){
Node cnode;
int i,len;
String str;

if(nodelist.getLength() == 0){
// 该节点没有子节点
return;
}
for(i=0;i 1)
System.out.println("      "+str+" "+len);
}
}
}
注意:上面的代码只是显示Node类型和Text类型的对象。它们的类型标识分别是1和3。 4.3 修改DOM文档 修改DOM文档的API在DOM level 2 Core规范中做了说明,jkd1.4中的org.xml.dom中实现了这些API。修改DOM文档操作主要集中在Document、Element、Node、Text等类中,这里给出的例子中是在解析出的DOM文档中增加一系列对象,对应与在XML文件中增加一条记录。 // 获得Root对象 Element root = document.getDocumentElement(); // 在DOM文档中增加一个Element节点 Element booktype = document.createElement("COMPUTES"); //将该节点转化成root对象的子节点 root.appendChild(cdrom); //在DOM文档中增加一个Element节点 Element booktitle = document.createElement("Title"); //将该节点转化成booktype对象的子节点 booktype.appendChild(booktitle); //在DOM文档中增加一个Text节点 Text bookname = document.createTextNode("understand Corba"); //将该节点转化成bookname对象的子节点 booktitle.appendChild(bookname); 4.4 将DOM文档转化成XML文件 // 获得将DOM文档转化为XML文件的转换器,在jdk1.4中,有类TransformerFactory // 来实现,类Transformer实现转化API。 TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); // 将DOM对象转化为DOMSource类对象,该对象表现为转化成别的表达形式的信息容器。 DOMSource source = new DOMSource(document); // 获得一个StreamResult类对象,该对象是DOM文档转化成的其他形式的文档的容器,可以是XML文件,文本文件,HTML文件。这里为一个XML文件。 StreamResult result = new StreamResult(new File(“text.xml”)); // 调用API,将DOM文档转化成XML文件。 transformer.transform(source,result); 这里提供了该例程的完整程序,该例程在windows 2000中jdk1.4环境中运行通过。 以上给出了一个例子,读者可以从中了解到对DOM操作的思路。因为对DOM的操作均遵循了DOM规范,所以也适用于其它语言对DOM的处理。 参考资料: http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-2000-1113 Java 2 Platform, Standard Edition, V1.4.0 API Specificaion <淘宝热门商品:
 

67.00 

【漂亮宝贝】童装打底裤名牌男童裤子背心T恤公主裙

X2-82103青蛙皇子童装130-155CM女中童T恤背心短裤两件套238

 

26.00 元  

时尚巴黎女人街 V 火爆这个冬季

附带女人我最大推荐魔法烘罩器电吹风机人性化冷暖风切换魔发冬夏


来源:程序员网

小小豆叮

Resin-2.0.3

<淘宝热门商品:
 

¥:9.99 

【黑龙江商盟】棋子儿平价美妆店-烟熏彩妆/假睫毛大全/新娘用品

买十送一全网最低价高级无痕透明根部自然浓密凌乱假睫毛仿真毛发

 

95.00 元  

韩国正品专卖!Intercrew LED手表/男


来源:程序员网

小小豆叮

用JAVA和XML构建分布式系统

可扩展标记语言(XML)作为一种简单的、中性的、易读的数据表示形式已经变得越来越流行,许多软件厂商宣布的“支持XML",意味着他们的产品将能生成或处理XML数据。XML也被看作再企业间交换数据最佳格式。它允许企业在所交换的数据的XML的文档类型定义(Document Type Definitions,DTDs)或模式(Schema)上取得一致。这些DTDs或Schema是独立于企业使用的数据库模式的。 本文将用研究在不同计算机之间通讯与处理XML数据的分布式系统的构建方法,主要是运行在不同的虚拟机上的JAVA应用之间的XML通讯。 XML通讯 万维网协会(World Wide Web Consortium, W3C)在XML规范中定义了XML的语法和语义。为了处理XML数据,XML文档必须经过解析。W3C定义了文档对象模型(DOM),它是应用程序员处理XML数据的接口。DOM已经有包括JAVA在内的许多语言的实现。JAVA应用程序可以通过DOM API来访问XML数据。XML解析器将产生XML文档的DOM表示。 图1说明了处理XML文档的JAVA分布式应用的简单模型。这个模型假设数据可以从诸如关系数据库之类的数据源得到。JAVA代码处理数据并最终产生DOM表示,这些代码表示为图中的处理器。 处理器代码将DOM代表的XML数据传给发送者。发送者是与接收者进行XML数据通讯的JAVA代码。接收者JAVA代码来接受XML数据,产生DOM表示的数据并把它传送给另一个处理器。简而言之,发送者和接收者抽象了DOM表示的XML数据的通讯。 发送者和接收者不是在同一个JAVA虚拟机上执行的。他们是通过分布式系统的构件来相连的。无论是接收者还是发送者都既是客户端又是服务器端,两者的数据传输都是双向的。 Xbeans 就像将要看到的一样,在本文中描述的发送者和接收者的三种实现方法都都是通过Xbeans来实现。Xbeans是一种接受XML数据作为输入,处理这个输入然后向下一个Xbeans输出XML结果的软件构件。Xbeans的输入输出都是XML的DOM文档,亦即传送给Xbeans的不是需要XML解析器解析的字符串,而是通过W3C的标准DOM API解析成了文档对象。图2说明了一个Xbeans。 Xbeans是JavaBeans,支持封装、重用、连接和客户化Java代码。通过适当的一些Xbeans和JavaBeans的设计工具,我们就能编很少的代码构建非常有用的分布式应用。 Xbeans从IBM的XML的JAVA开发工具包而来,在其上作了少量修改以便更适合分布式的应用。Xbeans能够从www.Xbeans.org的开放源码项目中免费获得。 实现发送方和接收方 下面将介绍用JAVA实现发送者和接收者的三种不同的方法。然后对每种方法作一个简单的分析。 方法一:用标准的web 服务器 这种方法将只是简单的将XML作为文本发送给远程计算机上的web服务器。发送方必须将DOM表示的XML转化为文本来与接收方进行通讯。然后,接受方必须将文本还原为DOM表示,如图3: 以下代码段用HTTP来实现发送者。这里用到了IBM Java开发包中的DOMWriter类来实现DOM表示到文本XML表示的转换。

public void documentReady(DOMEvent evt)  
throws XbeansException { 
try { 
URL receiver = new URL (getRemoteURL ()); 
URLConnection receiverConnection = receiver.openConnection(); 
receiverConnection.setDoOutput(true);  
//向发送者打开一个输出流然后发送文本形式的XML数据 
OutputStream out = receiverConnection.getOutputStream(); 
DOMWriter writer = new DOMWriter(); 
writer.setPrintWriter(new PrintWriter(out)); 
writer.documentReady(  
new com.ibm.xml.xpk4j.dom.DOMEvent( this,evt.getDocument())); 
out.close(); // 为结果打开一个输入流 
BufferedReader in = New BufferedReader( 
new InputStreamReader(receiverConnection.getInputStream())); 
// 处理结果:"OK" 表示成功;"Exception" 表示输入流串行化异常 
... 
in.close(); 
} catch (Throwable e) { 
e.printStackTrace(System.err); 
} 
} 

注意到以上的documentReady()方法用remoteURL属性得到服务器上的CGI脚本的URL。为了与HTTP兼容,CGI脚本类用字符串”Content-type: text/html"封装接收者的输出。这个脚本然后调用服务器上的the receiverMain()方法。 Main()函数只是简单的实例化接收者然后调用其receiveDocument()方法。

import org.xbeans.communication.stdio.receiver.*; 
public class receiverMain { 
static Bean theReceiver = new Bean(); 
public static void main(String[] args) { 
theReceiver.receiveDocument(); 
} 
} 
最后receiveDocument()方法的代码段将重新生成DOM表示以便进一步处理。这里用到了IBM的XML解析器。

DOMParser parser = new DOMParser(); // 构造解析器 
try { // 调用解析器 
parser.parse(new InputSource(System.in)); 
} catch (Throwable e) { 
throw new XbeansException("","receiver","io error parsing incoming document", 
"io error parsing incoming document "+e); 
} 
//将文档传向下一个bean 
DOMListener.documentReady(new DOMEvent(this,parser.getDocument())); 
方法二:通过JAVA远程方法调用串行化文档 这个方法通过JAVA远程方法调用(JAVA RMI)和DOM串行化(serialization)来从发送者向接收者传输XML DOM 文档。如图4: 以下代码用JAVA远程方法调用实现发送方与接受方的通讯.

public void documentReady(DOMEvent evt) throws XbeansException { 
if (DOMListener==null) { 
try { 
DOMListener = (DOMListener)Naming.lookup(getReceiverName()); 
} catch (Exception e) { 
throw new XbeansException( evt.getDocument().getNodeName(), 
"sender", "error obtaining remote receiver", 
"The name may be wrong or the network may be down."); 
} 
} 
DOMListener.documentReady(evt); } 
以下是接受方的JAVA 远程方法调用的实现。setName()方法将接受这传送给RMI注册(registry),documentReady()方法仅仅将接收到的文档传送给下一个组件。

public void setReceiverName(String newName) { 
try { 
if (receiverName!=null) Naming.unbind(receiverName); 
receiverName = newName; 
Naming.rebind(receiverName, this ); 
} catch( Exception e ) { 
System.out.println( e ); 
} 
} 
 
public void documentReady(Document incomingDocument)  
throws RemoteException, XbeansException { 
if (DOMListener==null) { 
throw new XbeansException(incomingDocument.getNodeName(),"rmiReceiver", 
"next component not established", "The component needs to be configured."); 
} 
DOMListener.documentReady(new DOMEvent(this,incomingDocument)); 
} 
方法三:CORBA-IIOP 第三方法用CORBA-IIOP(CORBA over Internet Inter-ORB Protocol)来传输数据。对象管理组织(OMG)正在建议扩展接口定义语言(IDL)将XML数据类型包括进去。这样,将来CORBA产品将能传输XML数据。如图5所示: 以下的OMG IDL给出了发送者和接收者CORBA实现的接口。

exception RemoteReceiverException { 
string remoteIdentifier; 
string documentName; 
string componentName; 
string message; 
string moreMessage; 
}; 
 
typedef sequence byteArray; 
interface XMLReceiver { 
void documentReady(in byteArray serializedDocument) 
raises(RemoteReceiverException); 
}; 
以下代码用JAVA串行化DOM和CORBA实现发送者。

public void documentReady(DOMEvent evt) throws XbeansException { 
Document documentToSend = evt.getDocument(); 
try { 
ByteArrayOutputStream bastream = new ByteArrayOutputStream(); 
ObjectOutputStream p = new ObjectOutputStream(bastream); 
p.writeObject(documentToSend); 
p.flush(); 
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( new String[0], 
System.getProperties()); 
XMLReceiver receiver = urlToObject(orb,getReceiverURL()); 
receiver.documentReady(bastream.toByteArray()); 
} catch (RemoteReceiverException rre) { 
throw new XbeansException(rre.remoteIdentifier, rre.documentName, 
rre.componentName, rre.message,rre.moreMessage); 
} catch (Throwable e) { 
throw new XbeansException("","sender", "error sending document "+e, 
"error sending document "+e); 
} 
} 
以下代码用JAVA串行化DOM和CORBA实现接收者。

public void documentReady(byte[] serializedDocument)throws RemoteReceiverException { 
// 反串行化字节流 
ByteArrayInputStream bais = new ByteArrayInputStream(serializedDocument); 
Document theDocument; 
try { 
ObjectInputStream ois = new ObjectInputStream(bais); 
theDocument = (Document)ois.readObject(); 
} catch(Throwable e) { 
throw new RemoteReceiverException(corbaName,"incoming document","receiver", 
"error deserializing document","error deserializing document"+e); 
} 
try { //将文档传向监听者 
local.DOMListener.documentReady(new DOMEvent(this,theDocument)); 
} catch (XbeansException xbe) { 
throw new RemoteReceiverException( xbe.remoteIdentifier(), 
xbe.documentName(),xbe.componentName(), 
xbe.message(),xbe.moreMessage()); 
} 
} 
分析: 测试表明,纯文本表示的XML要比DOM串行化表示性能更好。同时,解析DOM和文本所用的时间也要比用JAVA直接串行化和法串行化所用的时间少。 标准的web服务器方式的优势是其应用基础要广泛许多。CGI脚本能够在绝大多数web服务器上运行,而且,接受方能够很容易的通过URL标识。而对于RMI,则需要RMI注册。CORBA的解决办法则需要在服务器上安装对象请求代理(Object Request Broker,ORB ),而且,CORBA发送者的实现使用的是一个URL的命名模式而不是接收者的CORBA对象引用,用一个字符串与一个URL相联系,然后在客户端转化。 CORBA 和RMI支持JAVA 客户端到JAVA服务器的解决方案。没有CGI脚本也不需要从标准输入中读取编码异常。而且,不需要在发送者每次用XML通讯时都启动一个JAVA虚拟机。他们两则均支持接收者的自动激活。 JAVA RMI方式只能在JAVA代码之间工作,对于web服务器包括CORBA理论上能在任何编程语言之间通讯。对于JAVA串行化的DOM来说,即便是客户端和服务器端均需要是JAVA代码的要求不是问题,它还存在另外一个困难,即JAVA串行化要求客户端和服务器运行的是相同的DOM实现。 结论 正如上面所述,有许多方法可以实现在JAVA分布式应用中发送XML数据,每一种方法的性能和互操作性都是不同的。重要的是应该把XML通讯从分布式应用逻辑中抽取出来。也就是,实现发送和接受XML的代码应和应用逻辑的代码中分离出来。通过把代码打包成软件组件,就能够改变发送方和接受方的代码而不会影响到应用其余实现。 <淘宝热门商品:
 

 

义乌三冠店→大量贩の热销女性用品(零售+批发)

 

 

【化妆品大联盟】☆美丽佳人☆╯护肤·美妆~ 冲三冠特惠!


来源:程序员网

小小豆叮

Java2下Applet数字签名具体实现方法

Java2下Applet数字签名具体实现方法 北京 阿费 自从Java技术开始应用以来,人们对Java平台的安全性以及由于部署Java技术所引发的安全问题给予了极大的关注。特别是在1998年11月Java2发布后,Java的安全体系结构发生了根本的改进,对于终端用户而言,它可以保护文件和私人数据不被恶意的程序或病毒感染和破坏,鉴别代码提供者的身份。对于开发者而言,通过使用API方法,能够将安全性功能集成到应用程序中,因为API的体系结构能够定义和集成对特定的资源的使用权限、加密、安全性管理、策略管理,并提供了一些类来管理公钥/密钥对及信任用户群的公钥证书。同时系统管理员、开发者和用户可以使用它提供的工具管理钥匙库,在JAR文件中生成数字签名、签名的完整性检测、创建和修改策略文件。按照Java设计者的观点,Java安全包括2个方面的内容,首先将Java作为一种安全的平台提供给用户,在此平台上,可安全地运行Java程序;其次提供用Java编程语言实现的安全工具和服务,它使得诸如企业界这样一些对安全非常敏感的领域也可应用Java技术。本文将就这二个方面介绍Java2的安全性新特性以及该新特性下的Applet数字签名的具体实现方法。   Java2采用了如图1所示的新的安全体系结构,并基于这种安全体系结构提供了很多新特? 1.1 密纹访问控制   这种能力从一开始就在JDK中存在。但要使用它,应用程序的编写者不得不做大量的编程工作 <淘宝热门商品:
 

¥:21.0 

【华佗天然居】天然花草茶花茶中草药中药材

花草茶之瘦腿茶:迷迭香+柠檬草+马鞭草30包21元包快递美容减肥茶

 

288.00 元 

【19shop 超值正品】英国TOPMAN经典修


来源:程序员网

小小豆叮

关于EJB返回值的解决方案

相信很多人都有如此之困惑,得此解决方法不敢独享,公之于众,以利后来人。 声明:此方法的至于彭璐大侠,彭大侠可能不常上网,这麽好的方法也不告诉我等之小虾米,只好代劳了,彭大侠的email不便公开,应该是金蝶的人吧。 好了,不废话了,有两种方法: 1、用vector:

/** 
> * Finds all EJBeans with a balance greater than a given amount. 
> * Returns an Enumeration of found EJBean primary keys. 
> * 
> * @param balanceGreaterThan double Test Amount 
> * @return Enumeration EJBean Primary Keys 
> * @exception javax.ejb.EJBException 
> * if there is a communications or systems failure 
> */ 
> public Enumeration ejbFindBigAccounts(double balanceGreaterThan) { 
> log("ejbFindBigAccounts (balance > " + balanceGreaterThan + ")"); 
> Connection con = null; 
> PreparedStatement ps = null; 
> 
> try { 
> con = getConnection(); 
> ps = con.prepareStatement("select id from ejbAccounts where bal > ?"); 
> ps.setDouble(1, balanceGreaterThan); 
> ps.executeQuery(); 
> ResultSet rs = ps.getResultSet(); 
> Vector v = new Vector(); 
> String pk; 
> while (rs.next()) { 
> pk = rs.getString(1); 
> v.addElement(pk); 
> } 
> return v.elements(); 
> } catch (SQLException sqe) { 
> log("SQLException: " + sqe); 
> throw new EJBException (sqe); 
> } finally { 
> cleanup(con, ps); 
> } 
> } 
结论:不爽,不方便。 2、RowSet RowSet tutorial chapter : http://developer.java.sun.com/developer/Books/JDBCTutorial/chapter5.html rowset是个interface,需要有东西去实现它,sun的规范中给了三个class:cachedrowset,jdbcrowset,webrowset, 如果去查jdk1.4 doc和j2skee1.2,有rowset,却没有那三个class,一般的开发工具(至少我的wsad)中也是这样, 所以需要下jdbc2.0 opt-pack: http://developer.java.sun.com/developer/earlyAccess/crs/ 下下来了再怎么办呢? 装呗! 怎么装呢? setup呀! 没有呀? 啊,没setup呀,sun干什么吃的,连setup都不做个,也太懒了吧。 ///////////////////////////////// 哎,我们确实是都被ms惯坏了,看到只有jar,没setup就没辙了,大家好好想想,java最大的特性是什么,就是它的类库 可以自由扩充呀,现在明白该怎么做了吧: 1、解包,得到rowset.jar,放在哪随您的意,别丢了就行。 2、在您的开发工具中增加一个路径,如:ROWSET_PATH对应:d:jdk1.4jre owset.jar(和1的路径对应就行)。 3、右键您的工程文件,出现:property(大多数工具应该都有吧),加上rowset_path。 4、在您的源文件中:import sun.jdbc.rowset.*; OK,搞定!下面就看您的了。(当然也可以把rowset压到jre里去) 应该说rowset(其实主要是CachedRowSet)真的是个好东西,和ms ado的resultset和borland的tclientset非常相似, 最大的好处是Cache功能! 好了,看例子吧:

/////////////server端///////////// 
package example4; 

import java.sql.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import javax.naming.*; 
import javax.ejb.*; 

public class CoffeesBean implements SessionBean { 

   private SessionContext sc = null; 
   private Context ctx = null; 
   private DataSource ds = null; 
    
   public CoffeesBean () {} 
    
   public void ejbCreate() throws CreateException { 

       try { 
           ctx = new InitialContext(); 
           ds = (DataSource)ctx.lookup("jdbc/CoffeesDB"); 
       } 
       catch (Exception e) { 
           System.out.println(e.getMessage()); 
           throw new CreateException(); 
       } 
   } 

   public RowSet getCoffees() throws SQLException { 
        
       Connection con = null; 
ResultSet rs; 
       CachedRowSet crs; 

       try { 
           con = ds.getConnection("webCustomer", "webPassword"); 
           Statement stmt = con.createStatement(); 
           rs = stmt.executeQuery("select * from coffees"); 
            
           crs = new CachedRowSet(); 
           crs.populate(rs); 
           // the writer needs this because JDBC drivers 
           // don't provide this meta-data. 
           crs.setTableName("coffees"); 
            
           rs.close(); 
           stmt.close(); 
       } finally { 
           if (con != null) 
               con.close(); 
       } 
       return rset; 
   } 
    
   public updateCoffees(RowSet rs) throws SQLException { 

       Connection con = null; 

       try { 
           CachedRowSet crs = (CachedRowSet)rs; 
           con = ds.getConnection("webCustomer", "webPassword"); 
           // moves the changes back to the database 
           crs.acceptChanges(con); 
       } finally { 
           if (con != null) 
               con.close(); 
       } 
   } 

   // 
   // Methods inherited from SessionBean 
   // 
    
   public void setSessionContext(SessionContext sc) { 
       this.sc = sc; 
   } 
    
   public void ejbRemove() {} 
   public void ejbPassivate() {} 
   public void ejbActivate() {} 

    
} 


//////////////////client端////////////// 
package example4; 

import java.sql.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import javax.naming.*; 
import javax.ejb.*; 
import javax.rmi.*; 

class CoffeesClient { 

   public static void main(String[] args) { 

       try { 
           // init the bean 
           Context ctx = new InitialContext(); 
           Object obj = ctx.lookup("ejb/Coffees"); 
           CoffeesHome coffeesHome = (CoffeesHome) 
               PortableRemoteObject.narrow(obj, CoffeesHome.class); 
           Coffees coffees = coffeesHome.create(); 
            
           // get the rowset from the bean 
           CachedRowSet rset = (CachedRowSet)coffees.getCoffees(); 

           // find the Columbian coffee 
           while (rset.next()) { 
               String coffeeName = rset.getString("COF_NAME"); 
               if (coffeeName.equalsIgnoreCase(new String("Columbian"))) { 
                   // columbian coffee has gone up 10% 
                   rset.updateFloat("PRICE", 
                                    (float)(rset.getFloat("PRICE") * 1.10)); 
                   rset.updateRow(); 
               } 
           } 

           // finally send the updated back to the bean... 
           System.out.println("Calling update method"); 
           coffees.updateCoffees((RowSet)rset); 
       } 
       catch (Exception e) { 
           System.out.println(e.getMessage()); 
       } 
   } 
} 
例子很简单就不多讲了。 cheers. Robin Any question mailto:myvrml@263.net <淘宝热门商品:
 

16.0元  

【珠三角商盟】联合利众●减肥瘦身●丰胸美乳●私处保养●美容

 

保健品/滋补品 

淑芳阁_苗条姿_最有效的减肥瘦身与丰胸专卖店


来源:程序员网

小小豆叮

WAP缩略语集萃(eclipse整理!

3G - The Third Generation (Wireless Network / Technology) A AE - Authenticating Entity AIN - Advanced Intelligent Network AMPS - Advanced Mobile Phone System (analogue) ANSI - American National Standards Institute AP - Application Programming Interface AUC - Authentication Centre B BNF - Backus-Naur Form C CAN - Customer Access Network CCF - Call Control Function CCITT - Consultative Committee on International Telegraphy and Telephony CCAF - Call Control Agent Function CCS7 - Common Channel Signaling No.7 CDMA - CER - Call Event Record CIC - Carrier Access Code CID - Customer Identifier CLI - Calling Line Identification CLIP - Calling Line Identification Presentation CLIR - Calling Line Identification Restriction CNM - Customer Network Management CPE - Customer Premises Equipment CPI - Calling Person Identification CSD - Circuit Switched Data CSS - Customer Support System (Systems) CTIA - Cellular Telecommunications Industry Association CTI - Computer Telephony Integration D DECT - Digital Enhanced Cordless Telephony DTMF - Dual Tone Multi Frequency DCS1800 - Digital Cellular (1800Mhz) E ECMA - European Computer Manufacturer Association EDGE - Enhanced ETR - ETSI Technical Report ETSI - European Telecommunications Standards Institute F FMC - Fixed Mobile Convergence FMI - Fixed Mobile Integration FNN - Full National Number FCC - Federal Communications Commission G GoS - Grade of Service GPS - Global Positioning System GPRS - General Packet Radio Service GSM - Global System for Mobiles H HTML - HyperText Markup Language [[]HTML4] HTTP - HyperText Transfer Protocol [[]RFC2068] HLR - Home Location Register HDML - Handheld Device Markup Language(是phone.com的专利明语言,在WAP正式出现后逐渐淡出) I IANA - Internet Assigned Number Authority IMSI - International Mobile Subscriber Identity INAP - Intelligent Network Application Part IN - Intelligent Network IP - Intelligent Peripheral ISUP - ISDN Signaling User Part (signaling) ITU - International Telecommunications Union IVR - Interactive Voice Response IWU - Interworking Unit L LSB - Least Significant Bits M MAP - Mobile Application Part MML - Man Machine Language MoU - Memorandum of Understanding MSB - Most Significant Bits MSC - Mobile Switching Centre MTBF - Mean Time Between Failure MTBR - Mean Time Before Repair N NE - Network Element NMT - Nordic Mobile Telephone System NSN - National Significant Number NTP - Network Termination Point O OMS - Operations and Maintenance System OSS - Operational Support System P PABX - Private Automatic Branch Exchange PACTS - Public Access Cordless Telecommunication Service PBX - Private Branch Exchange PCN - Personal Communications Network PCS - Personal Communication Service PDA - Personal Digital Assistant PHS - Personal Handyphone System PIN - Personal Identification Number PLMN - Public Land Mobile Network PMTS - Public Mobile Telephone System PN - Personal Number POI - Point of Interconnect POTS - Plain Old Telephone Service PSTN - Public Switched Telephone Network PSTS - Public Switched Telephone Service PTO - Public Telecommunication Operator Q QEAN - Quick Entry Access Number QoS - Quality of Service R RFC - Request For Comments S SCE - Service Creation Environment SCF - Service Control Function SCP - Service Control Point SDF - Services Data Function SDK - Software Development Kit SDP - Services Data Point SIM - Subscriber Identity Module SIO - Services In Operation SMC - Security Management Centre SMF - Service Management Function SMS - Service Management System SMTP - Simple Mail Transfer Protocol SN - Service Node SQL - Structured Query Language SRF - Specialized Resource Function SSF - Service Switching Function SSP - Service Switching Point STD - Subscriber Trunk Dialling STP - Signaling Transfer Point T TCAP - Transaction Capability Application Part TMN - Telecommunications Management Network U UCS - Universal Multiple-Octet Coded Character Set UI - User Interface UMTS - Universal UPT - Universal Personal Telecommunication URL - Uniform Resource Locator [[]RFC2396] UTF - UCS Transformation Format V VAS - Value Added Service VLR - Visitor Location Register VMB - Voicemail Box VMP - Voicemail Platform W W3C - World Wide Web Consortium WAE - Wireless Application Environment WAP - Wireless Application Protocol WWW - World Wide Web WTA - Wireless Telephony Applications WTP - Wireless Transport Protocol WBMP - Wireless BitMaP WML - Wireless Markup Language WSP - Wireless Session Protocol WTAI - Wireless Telephony Applications Interface <淘宝热门商品:
 

17.80 元  

居家家--18个月上四皇冠,家居类信用最高卖家

简家 四皇冠信用 鲸鱼USB暖手鼠标垫D4063 冬天上网必备

 

 

徽商联盟】皇冠信誉店 联盟化妆品の屋


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例三)

实例三、计算 订单 的 总价格(如何取出正文的值)。 问题:请计算 orders.xml 所示的总价格 orders.xml 的源文件。 <订单> <商品 数量="21"> <名称>袜子 <单价>3.24 <商品 数量="1"> <名称>贝斯 <单价>4200.00 <商品 数量="5"> <名称>域名 <单价>60.50 <商品 数量="2"> <名称>书 <单价>99.00 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。 import org.xml.sax.*; import javax.xml.parsers.*; import java.util.Vector; /** * Title: XML Study, Sample 3 * Description: Count the Order Sum. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class CountSum extends org.xml.sax.helpers.DefaultHandler { private double totalPrice = 0.00; private StringBuffer content = new StringBuffer(); private Vector numberV = new Vector(); private Vector priceV = new Vector(); private double totalSum = 0.00; public CountSum() { } public static void main(String[] args) throws Exception { CountSum cs = new CountSum(); cs.createParser(); } public void createParser() throws Exception{ SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(this); xr.parse("http://localhost/orders.xml"); } // 取得 商品 中属性 数量 的值,并将它放入数组 numberV 中。 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("商品")) { String number = atts.getValue("数量"); numberV.addElement(number); //System.out.println(numberV); } content.setLength(0); } // **** 此方法将遍历 XML 文件,获取 文本 值。 public void characters(char[] ch, int start, int length) throws SAXException { content.append(ch, start, length); //System.out.println(content.toString()); // 打印出来,看看此方法是怎样运行的 } // **** 仅获取元素 单价 中的文本,并将它放入数组 priceV 中。 public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equals("单价")) { String price = content.toString(); priceV.addElement(price); //System.out.println(priceV); } } // 计算总价格 public void endDocument() throws SAXException { int num; double pr; for (int i=0; i
 

108.00 元  

电视购物热销.夏娃之秀魔力挺,让女人都有杀人"胸"器

 

鲜花速递/蛋糕配送/园艺花艺 

瑞锦记锦缎喜糖袋〓婚礼特制●上等材质●流行韩


来源:程序员网

小小豆叮

轻松玩转Java Web Start

陈臣 (chch1979@263.net) 2002 年 1 月 Java Web Start(以下简称JWS)是SUN提供的一种通过Web来部署和发布Java 程序的新技术,它既可以用来发布Application,也可以用来发布Applet,它获去年全球Java技术最佳创意奖。它仅在第一次运行时下载程序,以后的事情,就全全交给JWS,包括版本的自动更新和维护。这是我们曾经梦寐以求的事情,程序运行在客户端(本地运行,当然有足够的速度),但不用去安装配置客户端,也不用去考虑版本升级后对客户端的维护,这就是JWS提供给我们的好处之一。OK,下面我们就来看看如何玩转JWS,本文仅用发布Application来做说明。 系统环境:Win2000Professional+Tomcat3.2.1+JDK1.3。 一:JWS简介 JWS主要用来通过网络部署你的应用程序,它具有安全、稳定、易维护、易使用的特点。用户访问用JWS部署应用程序的站点,下载发布的应用程序,既可以在线运行,也可以通过JWS的客户端离线运行已下载的应用程序。对同一个应用程序,在第一次运行时下载,以后每次运行时,JWS的客户端会自动去探测是否有版本更新,有更新就自动下载新版本,没有更新就直接运行本地当前版本,所有的麻烦全由JWS去承担。好,下面我们就一步一步来搭建JWS 二:搭建支持JWS的Web站点 第一步:你的Tomcat3.2.1已经正常运转 第二步:找到TomcatHOME/conf下的web.xml文件,在其中添加 application/x-java-jnlp-file 以支持JNLP文件。 三:部署应用程序 第一步:开发你希望发布的应用程序 第二步:把应用程序及所用到的所有资源打成一个或多个jar包 第三步:如果你的应用程序不会用到任何运行这个应用程序的机器的本地资源,那么,你的应用程序就可以部署了。 第四步:如果你的应用程序用到了运行这个应用程序的机器的本地资源,那么,你的应用程序就必须先签名然后才可以发布。 第五步:如何给应用程序签名 1:首先确保你已经完全安装了Java2的环境,有keytool工具,它位于J2SE SDk的bin目录下。这一般不会有问题。 2:到Dos状态下,进入你需发布应用程序的jar包所在的目录,运行下面这句话 keytool -genkey -keystore myKeystore -alias jwstest 它将会提示你输入用户名、密码等,不用理它,按照提示随便输入即可,但一定要记住密码。运行结束它将会在当前路径下创建名为myKeystore的文件。 3:如果你想察看一下刚才生成的myKeystore文件的内容,可以使用下面这句话: keytool -list -keystore myKeystore 显示出来应该类似如下: Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry: jwstest, Tue Nov 23 19:29:32 PST 2001, keyEntry, Certificate fingerprint (Test): C3:A9:CD:F3:D3:AC:4D:3F:3C:5B:AF:9E:CF:0D:46:5C 4:对你需发布应用程序的jar包进行签名,运行下面这句话: jarsigner -keystore myKeystore yourtest.jar jwstest 其中yourtest.jar是你的jar包名,你需要修改它,别的就不必修改了。运行时会提示你输入密码,就是你刚才在生成myKeystore文件时设定的密码。 第六步:部署应用程序的jar包。 1:在Tomcat的webapps中新建目录JWSTest 2:在JWSTest下新建目录apps,META-INF,WEB-INF 3:在apps下新建目录images和lib 4:在META-INF中拷入MANIFEST.MF 5:在WEB-INF中拷入web.xml 6:把已经准备好的jar包拷入lib目录下 四:Jsp页面 第一步:编写用于Web访问的页面index.jsp如下: 第二步:在jsp中添加检测访问的客户端是否已经安装了JWS的客户端的代码,示例如下: 五:JNLP文件 第一步:下面我们来编写JWS的核心配置文件JNLP,有了它,才能将以上各部分联系起来,真正让JWS运转起来。JNLP文件符合标准的XML语法,实质就是一个XML文件。当然,编写它的最好方式是对已写好的JNLP进行改写。JWSTest.jnlp示例如下: spec="1.0+" codebase="http://你的IP:8080/JWSTest/apps" href=" JWSTest.jnlp"> YOUR Name JWS Test 第二步:部分JNLP的关键语法 元素 spec:必须是1.0及以上版本,这里用1.0+,不需修改。 codebase:资源的URL,是JNLP指向各连接的起始处,需自行修改。 Href:JNLP文件相对codebase的存放位置,和JNLP文件的全名,需自行修改。 元素 Title:发布的应用程序简单标题,需自行修改。 Vendor:发行商信息,可以写上你的大名,需自行修改。 Homepage:存放有关应用程序的相关文档的URL,如help文件等,可有可无。 Description:对应用程序的描述,可以有多对,可有可无。 Icon:用户下载你的应用程序后,在JWS里显示的图标的URL,应是gif或jpeg格式。需自行修改。 Offline-allowed:选择项,允许用户离线运行应用程序,一般都会有,不用修改。 元素 选择项,如果没有指明,默认是不允许应用程序访问用户的本地资源,即应用程序是沙箱运行。 如果设定为,则表示允许应用程序访问用户的本地资源。一般都会设定此值。 元素 元素 main-class:应用程序运行启动的主类 :应用程序运行时的参数,可以有多个,每一个参数用一对参数。 至此,你已经完全构建了运转JWS的各部件。 六:完整发布和测试 前面我们已经准备好了需发布的应用程序的jar包,也写好了用来访问的jsp文件和服务器端的核心jnlp文件。 第一步:在JWSTest下新建目录jsp。把index.jsp拷入jsp目录。 第二步:把jnlp文件直接拷入apps目录下。 第三步:在浏览器里输入:http://localhost:8080/JWSTest/jsp/index.jsp 即可访问到jsp页面。页面应出现JWSTest字样。 第四步:点击JWSTest,连接到apps下的JWSTest.jnlp文件,JWS启动,开始下载你发布的应用程序。 第五步:下载完毕,直接运行即可。以后,你也可以直接运行JWS客户端里已下载的应用程序。 不出意外,应恭喜你已经开始享受JWS带来的乐趣了。 七:常见问题 通过上面的讲述,你一定能体会到JWS的易用性。或许事情并没有那么简单,以我的使用经验,还会有许多问题出现,在这里挑几个经常出现的问题,给出相应解决方法,让大家少走弯路,而享受更多的乐趣。 问题一:JWS不能运行,JNLP文件像普通XML文件一样显示在Browser里 解决办法:请修改tomcat里,发布程序的路径中的web.xml。 在其中添加 application/x-java-jnlp-file 以支持JNLP文件。 问题二:不能下载资源或下载资源失败 解决办法:请卸载JWS的客户端,并将注册表里有关JWS的项目都删除,并确保program Files下的Java Web Start目录已被删除,然后,重装JWS。 问题三:下载资源中有未签名文件 解决办法:1:确保所有的jar包及其他资源都进行过签名。 2:确保整个资源中,没有中文的命名。好像签名工具不支持中文命名的文件名,所以未签到名。这可让我郁闷了一下午哦。 3:察看已经签名的jar包中,meta-inf路径下的jwstest.sf(jwstest是你在进行签名时-alias后的命名)文件,他详细的列出了所有已签名的文件,以分析签名失败的原因。 有关参考 详见 http://java.sun.com/products/javawebstart/ 关于作者 陈臣,就职于中关村某软件公司,软件工程师,scjp, 您可通过 chch1979@263.net 与他联系。 <淘宝热门商品:
 

4.00 元  

5钻【成都商盟】竹纤维内裤袜子毛巾超市~~收藏本店就有礼物送哦

特价 100%竹纤维毛巾 京杭丽人儿童毛巾27*48 50克/随机颜色

 

 

专做VIVI昕薇瑞丽韩日女装~


来源:程序员网

小小豆叮

评论:分布式不只是一个概念

新闻内容:      美国高新技术产业最近兴起了一个新行当,这个新行当通常被称做“分布式运算”(distributed computing)或“点对点”(peer to peer)服务供应商,他们的主要任务是把公司职员的个人计算机所闲置的运算能力汇集起来,帮助客户进行复杂的研究工作并节省其购买超级计算机的费用。   也就是说,这类公司把客户复杂的研究问题分割成好几个可以独立运算的部分,然后通过网络把这些分割后的问题分发给下属数千台个人计算机进行处理,这时候每台个人计算机就变成类似Napster网站(提供MP3音乐文档交换服务)的交换系统,等到运算结束后再把个别的结果回传给中心计算机汇总,最后得出问题的答案。   这种构想其实很简单,因为个人计算机就像人脑一样有许多部位的能力尚未开发,所以这些公司的任务就是把这些能力开发出来,加以结合后就能发挥极大的作用,其效率甚至远远超过一台超级计算机。   分布式运算,可能逐渐取代超级计算机   这种构想起源于加州的“寻找外星智能生命协会”。这个协会从1999年5月开始寻找有兴趣参与研究的成员。通过分布式运算方式,该协会把成员个人计算机多余的运算能力结合起来,结果发现其探测外星人电磁波信号的译码能力,竟然远远超过最大型的超级计算机。   尽管目前“分布式运算”的使用仍受到诸多限制,但却有逐渐取代超级计算机的趋势。目前生物技术研究人员已经通过这种方式处理复杂的程序,以寻找基因;经济学家也通过它得出数百万种股市变化可能性的组合。另外,企业也可以使用这项服务测试其网站网页被下载的速度。   仅仅购买一台超级计算机的价格可能就高达1.1亿美元,因而“分布式运算”的客户只需付出购买或者租用超级计算机的一小部分经费,就可以完成其研究目标。这正是“分布式运算”供应商赖以生存的基础,它们可以帮助客户获得超级计算机般的运算能力,客户却不必付出使用超级计算机所需的高昂代价。   洋基集团的研究人员高曼表示:“这是高新技术产业开创的新领域,即借用个人计算机的力量,发挥出超级计算机的效果,再把这样的服务卖给企业。”不过,这样的网络联结可能提供了另一种病毒传播的渠道,但专家们表示在通过复杂的加密程序保护后,这样的风险已大大降低。   在“分布式运算”服务供应商们刚刚露头的时候,他们在吸收愿意提供个人计算机闲置运算能力的成员时不用支付任何成本,因为他们保证这些计算机将用于公益事业。例如United Devices这家公司是将“分布式运算”能力应用于癌症研究。沃壮是United Devices的成员之一,他说:“这是我当初加入这家公司的原因。”   但随着越来越多的公司借此牟利,许多当初持支持公益事业态度加入的成员开始犹豫是否要让自己的计算机成为别人的摇钱树。   United Devices的首席执行官修巴德表示:“当我们接到商业合同时,将会向成员发放酬金。”这家公司每个月都会按照成员个人计算机的贡献程度,向前200位成员发放5-1000美元不等的津贴。   Porivo Technology公司是另一家“分布式运算”服务供应商,该公司从这个月开始实行有偿使用个人计算机闲置能力的作法。这家公司的创办人兼战略发展副总裁何密斯说:“平均每个月每位成员可以领到15-20美元。”目前该公司一个月向客户收取的费用最多高达2万美元,向成员支付的金额最多为每月45美元。   不过United Devices公司表示,在金融风险日益增高的时候,应该尽量避免实施这样的付费制度。修巴德表示:“要公司负担如此大的非固定成本,并不是明智之举。”   然而United Devices的劲敌,为Scripps Institute提供艾滋病研究所需运算能力的Entropia公司,虽然也提供商业服务,但却拒绝向参与成员支付报酬。该公司创办人兼首席技术官安得鲁·陈说:“当成员知道个人计算机是用于有意义的研究后,他们将会十分高兴。”   分布式软件,让软件变得虚无缥缈   分布式概念还为软件的发展激发出了新的灵感。过去20年来,互联网的发明及推广使得数以百万计的计算机能够彼此相连,最近出现的高速网络服务则进一步加强了计算机连结的程度,这使得分布式软件的发展向前跨出了重要的一步。   一些软件设计师将这种发展方向称为远离计算机桌面,让软件变得虚无缥缈。在传统意义上,软件就是一个产品,储存于磁盘或者光盘上,它是用户使用计算机的工具之一。如今,软件公司正致力于通过铜线、光纤及电磁波所构成的高速网络,让软件流动化,也就是说,让软件分布在整个网络上。   这个构想对那些想要甩开传统桌面图形用户界面的软件设计师非常有吸引力。事实上,分布式运算是一个宏大的理想,不论是学术领域还是产业界的龙头公司,几乎都在竞相追逐这一目标。   也许分布式运算的最佳典范就是互联网的网域名称系统,网域名称是一个存在于很多服务器之中的庞大数据库,通过网络的连结,它可以迅速向上网者提供网址上的资料。相比之下,未来十年之内分布式应用软件对于整个社会的影响将不可限量,它的触角可能会伸向能源管理,也可能伸至交通控制系统。   美国加州一家新公司Applied Minds的创办人兼首席计算机设计师席立斯表示:“原则上大家都希望某样东西能够固定在某处,这样一来四面八方的人士都可随意使用。”但是他接着说,“过渡到软件服务是未来不可避免的趋势,没有人愿意花钱买软件,但所有人都希望能够使用软件。”席立斯解释说:“拥有软件反而于己不利,因为你还必须维修、升级,如果你买了一台新的计算机,你必须重新安装软件。”   过去两年来,一批新型公司已开始积极运作,希望能使分布式软件的美梦成真。这些新公司自称为应用软件服务提供商,他们竭力为产业界提供所需的软件,不过随着市场环境的变化,有些公司目前已从市场上消失,但仍有部分公司继续提供服务。   如今国际商用机器(IBM)、微软及太阳等三家计算机产业的领导厂商也准备趟这趟浑水,他们正在研发新软件,为远离桌面的目标奠定基础。   不过新的系统都是以各家公司的商业策略为出发点。例如微软希望通过提供分布式软件服务,来巩固其桌面软件霸主的垄断地位。IBM及太阳则希望打破微软软件的市场龙头地位,他们说服研发人员自行设计出不同于微软的软件,写出一套网络标准的新程序。   然而,分布式运算将会增加软件的复杂性。网络搜寻引擎Google董事长舒密特表示:“事实上分布式运算非常困难,它表面上看起来容易,但实际操作却困难重重,它必需克服各种不同的网络安全及网络系统。” <淘宝热门商品:
 

1.50元  

星钻喜铺◣皇冠信誉◢{100%满意婚庆一站式店铺}特色婚庆用品大全

 

128.00 元  

【广州商盟】*大学生淘宝皇冠第一店-鞋神--三人行出口剩余旗舰店

【大学生皇冠店】new balance纽巴伦378经典款 天蓝


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例一)

基于事件驱动的解析接口 SAX (实例一) SAX vs. DOM DOM是基于树结构的一种接口;SAX是基于事件驱动的解析接口。 有什么区别呢? 1、SAX 可以解析任意大小的文件,而 DOM 解析的文件大小则和硬件有关。DOM 需要将整个文件加载到内存,而 SAX 不需要。 2、因为 SAX 是不把文件加载到内存,所以不能对文档进行随机存取;而 DOM 可以做到。 3、SAX 相对 DOM 来说是简单易用。 4、如果要从文档的简单系列中获取信息,SAX 是最快的方法。 实例一、查查有多少本书? 题目是要查出来下面的 XML 文件 books.xml 里有多少本书。 XXX1 Thinking in Java 60.00 XXX2 Thinking in C++ 56.00 Slepwormzz My Dirty Mind 8.99 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。 import org.xml.sax.*; import javax.xml.parsers.*; import java.io.IOException; /** * Title: XML Study, Sample 1 * Description: Count My books. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class BookCounter extends org.xml.sax.helpers.DefaultHandler{ private int count = 0; // 定义一个计数器 public BookCounter() { } // 主程序 public void countBooks() throws Exception { // 创建一个新的 JAXP 的 SAXParserFactory 实例,并且配置它。在 JAXP 包的例子中可以看到此种方法 SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); // 试一下改为 true XMLReader xr = null; try { SAXParser sp = spf.newSAXParser(); xr = sp.getXMLReader(); } catch (Exception e) { System.err.print(e); System.exit(1); } xr.setContentHandler(this); try { xr.parse("http://localhost/books.xml"); //进行语法分析 } catch (SAXException se) { System.err.println(se.getMessage()); System.exit(1); } catch (IOException ioe) { System.err.println(ioe); System.exit(1); } } // 当每次碰到一个 book 元素的时候,将 计数器 加一。此方法在遇到第一个元素的时候开始执行 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("book")) count++; } // 输出 计数器。此方法在分析文档完成的时候执行 public void endDocument() throws SAXException { System.out.print(count); } public static void main(String[] args) throws Exception { BookCounter bc = new BookCounter(); bc.countBooks(); } } 我们可以看到输出了结果 为 3 试着把 books.xml 文件改成错误的结构,看看 会有什么例外抛出 <淘宝热门商品:
 

¥:9.99 

【黑龙江商盟】棋子儿平价美妆店-烟熏彩妆/假睫毛大全/新娘用品

买十送一全网最低价高级无痕透明根部自然浓密凌乱假睫毛仿真毛发

 

 

【25元或以上商品任意2件包运】【时尚卓尔】-个性随我秀


来源:程序员网

小小豆叮

基于Internet的软件工程策略

作者:Yao Zheng  来源:CoSoft 我有话说……   Internet的发展和应用正在不断超越人们的想象,融入社会生活的各个角落,将对各行各业产生深远的、不可逆转的影响。针对软件产业而言,Internet时代对于软件开发进度提出不断增长的挑战性要求,并产生了许多新思想和新观念,对原有的一些传统软件工程理念带来了冲击,Linux的成功开发实践、开放源码思想的不断普及、大教堂和市集型开发模式的碰撞等都是最直接的体现。显然,如何使得软件企业能够从容面对时代的变迁,把握Internet所带来的机遇和挑战,具有重要意义。   近年来,开放源码思想在国际上越来越受到人们的重视,在这个思想下已经成功开发了一系列著名软件,比如Linux就是其中典型代表。开放源码思想与Internet有着内在的天然联系,通过二者的有机结合能够将许多人的智力集聚到一起,反映了一种新的软件开发思路,本节试图探究其成功经验。   相对传统软件工程而言,开放源码社区似乎没有准备接受或实践现代软件工程过程,但他们的确在开发适用于特定用户团体的软件,这些软件通常是极具价值的、可靠的、被广泛接受的和高可用的。那么,究竟什么样的开发过程正在开放源码社区中被常规应用和实践呢?一项研究表明,有五种软件开发过程在开放源码社区得到广泛应用:   1) 需求分析和说明   2) 受控的版本管理、系统构建和按阶段的增量发布   3) 维护被看作是演进式开发、重新精练细化和重新发行   4) 项目管理   5) 软件技术转移   以上每个过程都与传统软件工程规定体现出不同之处,而且没有哪个过程应被独立构造或凌驾于其他过程之上。更进一步,这些过程相互之间通常是并行开展的,而不象传统软件生命周期模型中那样严格的或部分的按序进行,开放源码软件开发从本质上讲是一种复杂的由社会-技术过程、开发条件和动态产生的开发上下文所组成的网络,以Internet为基础支撑平台,并随着Internet的发展而不断完善。   对于许多开放源码项目而言,开发人员对于是否遵循了某种规定的软件工程方法和过程并不关心,有些项目甚至没有特定的用户和发布截止期限,但是诸如“经常发布”、“简化设计”、“测试”、“编码标准”、“集体参与”等基本原理却被本能地执行着。   对于开放源码软件协同开发原理的经典论述来自开源社区领袖之一的Eric Redmond的《大教堂与市集》一文,在该文中作者形象地将传统的严格管理的软件开发活动比喻为构筑大教堂的行为,而将分布于Internet之上的开放源码社区的协同开发活动则看作是市集行为,作者根据亲身经历系统地论述了市集型开发的基本方法和哲学问题,阐释了开放源码社区成功的内在原因,对于传统软件开发不无借鉴之处,比如“早发布、常发布、听取用户的建议”、“把用户当做协作开发者和Beta测试人员”、“聪明的数据结构和笨拙的代码要比相反的搭配工作的更好”、“最好的设计不是再也没有什么东西可以添加了,而是再也没有什么东西可以去掉”、“好程序员知道该写什么,伟大的程序员知道该重写(和重用)什么”等等。   目前,人们对于基于开放源码的Internet协同开发实践还缺乏深入研究和理解,但是已经得到越来越多的软件工程人士的关注,并取得一定的研究成果。一个软件工程研究小组在过去5年中深入研究了几个大型的开放源码系统的体系结构和进化过程,包括Linux、GCC、VIM、Mozilla和Apache,发现他们与类似的商业系统之间表现出令人感兴趣的不同之处,比如,开放源码软件的体系结构通常是可浏览的以允许开发人员进行交互,对于那些可能阻碍程序理解(因为程序员通常是分布在Internet上各个角落互相独立的工作)的体系结构部分进行特殊声明;从同类的开放源码软件如Web服务器中可以提取其共性的参考体系结构,而在商业软件公司中却难以通过Web服务器体系结构获得几种不同的实现;开放源码软件的体系结构和开发模式是导致其超线性增长的主要因素,并且被尽可能设计的易于移植,其发行版通常不是针对特定平台,而是将各种平台的共性抽象到一个发行版中,通过配置工具来帮助构建系统。   另外,针对如何借鉴开放源码项目的经验用于指导商业软件项目也有相关研究成果,该项研究表明,尽管完全利用开放源码开发模式来代替传统商业软件开发模式目前看来还不太可能,但无疑可以相互借鉴经验教训而获得收益。研究人员认为,一些可供商业软件项目借鉴的开源项目经验包括:   人员组织——开源项目通常由很少的核心成员完成多数开发和升级任务,这一点与商业软件开发类似,但差别在于这些任务是如何在核心小组内分配的。开源项目通常是自发形成,职责的分配是基于对开发人员如何看待他们在项目中的角色的推理而确定,并不是硬性指派产生,这一点无疑对于商业软件的管理具有借鉴意义。   非正式交流——在Internet协同开发活动中非正式交流对于项目成员间的协调极其重要,邮件列表、论坛等是常用工具,无论开发人员在文化、地域和时区方面是否存在差异。商业软件应借鉴这种做法,而不必拘泥于严格的、形式化的交流渠道。   增强的用户支持——许多用户都同意这种观点,即多数商业软件公司在进入售后支持阶段时就可能面临悲惨的失败命运。而开源项目的用户支持工作却有良好成绩,因为大量的用户愿意提供关于开源产品的反馈信息。因此,商业软件项目应增强用户之间、用户与开发者之间的交互,从而获得改进的售后支持以及更有意义的错误报告。   显然,随着人们对于基于开放源码的Internet协同开发模式的不断研究和深入理解,必将对未来的软件工程实践产生极其深远的影响。以下按照传统软件工程领域的常规做法,对于开放源码软件的协同开发活动总结出所谓“最佳实践”,以增进读者的感性认识: (一)技术交流   软件开发人员需要花费大量时间用于相互之间的通讯交流,清晰和高效的技术交流对于维持团队间的同步和允许掌握关键知识的个人在需要时利用其知识都是必需的。开放源码社区的一个基本原则是技术交流应当在公共论坛中进行,邮件列表是开放源码交流的基石。不仅如此,开放源码项目需要在精确交流技术细节和小组决策方面得到支持 (二)版本控制、文档管理和发行   任何软件开发项目都需要版本控制,开放源码项目在这方面更是需要强大灵活的支持,以使得许多并行的开发人员可以同时工作在相互重叠的文件集上。开放源码项目也需要设计文档、技术文档和用户文档方面的标准模板,并需要一个良好组织的Web站点来发行这些文档。但是,开放源码项目的本质要求这些文件可供全世界访问,同时日常管理成本则被最小化,维护工作被分配给整个开发社区中的成员。 (三)质量保证   开放源码软件产品取得令人瞩目的质量水平,这一点在封闭源码开发世界被认为是最困难和最耗费资源的软件开发工作之一。开源软件取得高质量的原因主要包括以下三方面:(1)开发人员是根据自己在相关应用领域的兴趣和知识来自我选择的;(2)开发人员对于项目需求心照不宣,因为他们自己就是软件的用户;(3)技术交流(包括错误报告)是公开进行的。此外,调试工作也由于被分解到许多具有不同知识背景的人手中而更高效。 (四)构建和测试管理   开源项目的开发活动是在许多开发人员中发生的连续和并行的行为,有时某个开发人员的更改可能与其他开发者进行的更改发生冲突,通常情况下版本控制活动能够解决这些冲突,但是有时却不行。那些被开发用来支持软件经常自动构建和测试的工具成为帮助尽早发现这类逻辑冲突的强大工具。 (五)项目管理   任何项目都需要明确的目标、资源配置和进度安排,开源社区采取独特的、灵活的方式来解决这类问题——共享的“TO-DO”列表用于跟踪那些需要完成的任务,个人的“TO-DO”列表帮助开发人员保持进度,里程碑列表则基于用户和开发者的反馈设置了灵活截止期限。 (六)知识管理   知识是区分开发高手和初学者的最具价值的资源,高效地共享知识则是开源社区成功的关键所在。清晰地管理知识可以帮助减少初学者的学习曲线,从而降低潜在贡献者的入门壁垒,同时自动地将专家用于培训他人的负担降至最低限度。 <淘宝热门商品:
 

188.00 元  

地球都踩在脚下

T-MAC8麦迪8代 麦8 08-09赛季麦迪篮球鞋 白黑红 阿迪达斯adidas

 

28.00 元  

保健食品,散装,正装由你选


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例二)

基于事件驱动的解析接口 SAX (实例二) 实例二、查查看我的 书架 中有多少本 小说 书(获取元素的属性值) 题目是要查出来下面的 XML 文件 books.xml 里有多少本 小说。 <书架> <书 类别="参考书"> <著者>谭浩强 <书名>学习C <价格>20.00 <书 类别="小说"> <著者>吴承恩 <书名>西游记 <价格>120.56 <书 类别="小说"> <著者>曹雪芹 <书名>红楼梦 <价格>208.99 <书 类别="小说"> <著者>睡虫 <书名>下月出版 <价格>0.00 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。请注意将要分析的 xml 文件放在 http://localhost/books.xml 或者更改此 URI import org.xml.sax.*; import javax.xml.parsers.*; /** * Title: XML Study, Sample 2 * Description: Count fictions in my shelf. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class GetAtts extends org.xml.sax.helpers.DefaultHandler{ private int count = 0; // 定义一个计数器 private boolean isFiction; public GetAtts() { } // 创建一个新的 JAXP 的 SAXParserFactory 实例,并且配置它。 public void createParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(this); xr.parse("http://localhost/books.xml"); } // 当每次碰到一个 book 元素的时候,将 计数器 加一。此方法在遇到第一个元素的时候开始执行 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("书")) { String category = atts.getValue("类别"); ///**** 获取 类别 的值 System.out.println(category); //打印 类别 的值 isFiction = (category != null && category.equals("小说")); //如果 类别 的值为 小说 则将计数器加一。 if (isFiction) count++; } } // 输出 计数器。此方法在分析文档完成的时候执行 public void endDocument() throws SAXException { System.out.print(count); } public static void main(String[] args) throws Exception { BookCounter ga = new GetAtts(); ga.createParser(); } } 输出结果 为 参考书 小说 小说 小说 3 <淘宝热门商品:
 

 

哈喽嘟嘟-柠檬绿茶.心蓝t透0.双生儿香港平价店.

 

 

『女人天生是妖精』店内商品均为现货 拍下后可直接留言修改运费


来源:程序员网

小小豆叮

J2EE项目中开发团队的组建 

J2EE这种应用模型允许不同的开发人员同时进行开发的各个元素。这里阐述一下对不同层次 的设计人员,开发人员的技术要求。对以下几个分类进行描述。 • 设计师组建团队 • 表现逻辑层的团队角色 • 业务逻辑层等团队角色 • 数据库访问层的团队角色 团队的组成可以根据人员的数量和系统的范围大小。例如,不一定所有的角色都要分配,有些人可以担当不能的角色。 ****** 设计师 ****** 在基于组件的应用系统开发中,一个或几个人必须对这个系统的整体需求有全面的了解,比如系统的控制流程,和其他的接口等等。有些公司称这个角色为总工程师,不管怎么叫,这个角色非常重要,他承担协调不同开发小组之间的工作,帮助他们考虑系统这个“大图”。 ******************** 表现逻辑层的团队角色 ******************** 在表现层,用户界面是动态生成的。需要如下开发人员: • Java servlet 开发人员 • JSP 开发人员 • HTML 设计人员 • 美工人员 • 客户端的JavaScript 开发人员 Servlet 开发人员建立表现层的逻辑,而其他人员建立表现的形式。 Java Servlet 开发人员 Servlet处理页和页之间的浏览,会话管理,简单的输入验证。Servlet也将业务逻辑的元素连接起来。 Servlet开发人员必须理解一些相关事宜,HTTP请求,安全,多语言,和一些页面元素如session, cookie,超时等等。J2EE的应用里面,servlet必须用Java来写,Servlet可能会调用JSP, EJB, JDBC等等。因此,servlet开发人员要与应用系统的其他人员紧密合作。 JSP 开发人员 JSP开发人员与servlet开发人员密切合作来定义系统的表现层页面。即使在复杂的开发项目里,JSP和servlet的开发人员也可能是一个人。 然而,如果一个系统中大部分Java在servlet而不是在JSP里,JSP人员就不必对Java非常熟悉。 HTML 设计人员 HTML 设计人员对HTML页面进行优化。例如,他可能要完成以下任务: • 保证在不同的浏览器中所有的页面都能正常显示 • 保证低速的调制解调器访问也不受影响 • 对JSP设计人员的页面进行进一步的优化 美工人员 美工人员创建图片等等。这些图片要能小体积,快速下载。美工与HTML页面人员紧密合作。 客户端的JavaScript 开发人员 使用客户端的JavaScript有很多原因。比如,可以处理简单的输入验证,不必提交给服务器,还可以让用户界面更生动。这个角色和servlet, JSP人员紧密合作。 ******************** 业务逻辑层的团队角色 ******************** 业务逻辑层包含业务规则和业务实体。需要以下人员: • Session bean 开发人员 • Entity bean 开发人员 Session Bean 开发人员 Session beans包含业务处理和业务规则的逻辑。比如,一个session bean 可能设计成计算一个支票的税率。如果一个系统面临处理经常变化的复杂逻辑,而又大量使用session bean,结果是,session bean就需要不断的更新。 Session bean 的开发人员一般是一个领域的专家,理解复杂的,专门领域的逻辑,还有数据验证的规则。这个人员与servlet和entity bean开发人员紧密合作。 Session bean可能需要调用JDBC接口,和其他的EJB。无状态的session bean系统运行的会更好一些。因为,如果计算费率是一个有状态的session bean,系统就必须访问一个保存bean的状态信息的服务器。如果那个服务器恰巧出现问题,整个流程就会受阻。 Entity Bean 开发人员 Entity bean代表永久的对象,如一个数据库中的一条记录。Entity bean开发人员的任务是设计一个面向对象的所有业务数据的组织图。建立面向对象的试图意味着要将数据库中的表(关系型的)映射成entity bean。例如,开发人员需要将客户表,发票表,和订单表转换成相应的客户,发票,和订单对象。 一个entity bean 开发人员与session bean, Servlet开发人员密切合作,保证应用系统提供快速的,灵活的,可扩展的对业务数据的访问。 Entity bean 可能会大量的调用JDBC接口。而entity bean 之间的调用会很少。 ********************** 数据库访问层的团队角色 ********************** 在数据库访问层,开发人员需要建立关系型数据库的ER图,数据字典等等相关文档。所有对数据库的修改,访问等等权限操作都要经过数据库访问层开发人员。这个角色在大部分项目中担当DBA的角色。 团队组建之后,就可以开始设计用户界面。 ************ 设计用户界面 ************ 建议从前到后开始设计应用系统。就是说,先设计用户界面,再设计EJB,这样效率最高。 安博公司已经做了大量的界面设计工作,以后的工作完全可以参照已有的设计。下面提一些常用的建议性问题: • 页面流程是什么? • 每个页面上的命令按钮是什么? • 是否适用frame? • 是否有公司标准的Logo,广告条幅? • 在什么地方需要登录过程? • 多语言的问题? 这些和设计servlet, JSP相关。 <淘宝热门商品:
 

188.00 元  

地球都踩在脚下

T-MAC8麦迪8代 麦8 08-09赛季麦迪篮球鞋 白黑红 阿迪达斯adidas

 

¥:21.00 

【义乌绘美家居】【收藏本店送礼品】


来源:程序员网

小小豆叮

Servlet运行环境所需的软件安装及WAP编程环境设置

(本教程以Windows2000/Jswdk1.01/jdk1.3为例) 1:下载Jswdk1.01(jswdk1_0_1-win.zip 745Kb) 2:下载Jdk1.3(j2sdk1_3_0-win.exe 29.4 MB) 安装完以上两个文后,请在Windows2000上做如下的Path,PathClass设置(尚未设定IIS WAP运行环境的,可参照WAP86的"WAP建站指南"): (1):右击“我的电脑”--“属性”---“高级”--“环境变量” (2):在“系统变量”框中“新建....” 变量名 “path” 变量值 “d:\jdk1.3路径\bin” (3) “确定”后然后再“新建....” 变量名 “classpath” 变量值 “d:\jdk1.3\lib\tools.jar;D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\lib\servlet.jar;D:\xing\servlet \swdk1_0_1-win\jswdk-1.0.1\webserver.jar” 启动服务:执行jswdk-1.0.1目录下的startserver.bat 注:安装路径视你的安装情况而定,请自行修改之,下同! 3、 测试是否安装设置成功: 在IE中键入:“http://localhost:8080”如果成功,你将看到如下页面: 4、 增加一个测试用的虚拟目录(testwml): (1)、 打开jswdk-1.0.1目录下的webserver.xml,并在 和之间加入: “” (2)、 在“D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\”下建立 “WEB-INF\servlets\”目录。 (这样,当在WAP模拟器中键入:http://localhost:8080/testwml/servlet/wap86test Jswdk就会自动在testwml目录下的WEB-INF\servlets\中去找wap86test.class) (3)、 重新启动服务:执行jswdk-1.0.1目录下的stopserver.bat 然后再执行startserver.bat [b]用servlet生成WML[/b] 1.源程序 wap86test.java: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class wap86test extends HttpServlet { public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/vnd.wap.wml"); PrintWriter out = response.getWriter(); out.println(""); out.println("out.println(" \"http://www.wapforum.org/DTD/wml_1.1.xml\">"); out.println(""); out.println(""); out.println(" "); out.println("Date and Time Service "); out.println("Date is: "+ new java.util.Date()); out.println(" "); out.println(""); out.println(""); } } 2:编译源程序 “开始”--“运行...” ---键入“javac D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\testwml\WEB-INF\servlets\wap86test.java” 此时你以看到在"D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\testwml\WEB-INF\servlets\"目录下会多出一个wap86test.class 文件!   如果你想看到更多的编译信息,请在MS-DOS窗口中输入以上命令. 3:大功告成! <淘宝热门商品:
 

68.00 元 

超人气神奇魔水 柔嫩细滑肌肤一喷即成

 

185.00 元  

累计销售1000多件 G-STAR 雪纺短款夹克


来源:程序员网

小小豆叮

一个文件上传JavaBean



package com.upload; 

import java.io.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.ServletInputStream; 
import javax.servlet.ServletException; 

public class upload{ 
private static String newline = "
"; 
private String uploadDirectory = "."; 
private String ContentType = ""; 
private String CharacterEncoding = ""; 

private String getFileName(String s){ 
int i = s.lastIndexOf(""); 
if(i < 0 // i >= s.length() - 1){ 
i = s.lastIndexOf("/"); 
if(i < 0 // i >= s.length() - 1) 
return s; 
} 
return s.substring(i + 1); 
} 

public void setUploadDirectory(String s){ 
uploadDirectory = s; 
} 

public void setContentType(String s){ 
ContentType = s; 
int j; 
if((j = ContentType.indexOf("boundary=")) != -1){ 
ContentType = ContentType.substring(j + 9); 
ContentType = "--" + ContentType; 
} 
} 

public void setCharacterEncoding(String s){ 
CharacterEncoding = s; 
} 

public void uploadFile( HttpServletRequest req) throws ServletException, IOException{ 
setCharacterEncoding(req.getCharacterEncoding()); 
setContentType(req.getContentType()); 
uploadFile(req.getInputStream()); 
} 

public void uploadFile( ServletInputStream servletinputstream) throws ServletException, IOException{ 

String s5 = null; 
String filename = null; 
byte Linebyte[] = new byte[4096]; 
byte outLinebyte[] = new byte[4096]; 
int ai[] = new int[1]; 
int ai1[] = new int[1]; 

String line; 
//得到文件名 
while((line = readLine(Linebyte, ai, servletinputstream, CharacterEncoding)) != null){ 
int i = line.indexOf("filename="); 
if(i >= 0){ 
line = line.substring(i + 10); 
if((i = line.indexOf(""")) > 0) 
line = line.substring(0, i); 
break; 
} 
} 

filename = line; 

if(filename != null && !filename.equals(""")){ 
filename = getFileName(filename); 

String sContentType = readLine(Linebyte, ai, servletinputstream, CharacterEncoding); 
if(sContentType.indexOf("Content-Type") >= 0) 
readLine(Linebyte, ai, servletinputstream, CharacterEncoding); 

//File(String parent, String child) 
//Creates a new File instance from a parent pathname string 
//and a child pathname string. 
File file = new File(uploadDirectory, filename); 

//FileOutputStream(File file) 
//Creates a file output stream to write to the file represented 
//by the specified File object. 
FileOutputStream fileoutputstream = new FileOutputStream(file); 

while((sContentType = readLine(Linebyte, ai, servletinputstream, CharacterEncoding)) != null){ 
if(sContentType.indexOf(ContentType) == 0 && Linebyte[0] == 45) 
break; 

if(s5 != null){ 
//write(byte[] b, int off, int len) 
//Writes len bytes from the specified byte array starting 
//at offset off to this file output stream. 
fileoutputstream.write(outLinebyte, 0, ai1[0]); 
fileoutputstream.flush(); 
} 
s5 = readLine(outLinebyte, ai1, servletinputstream, CharacterEncoding); 
if(s5 == null // s5.indexOf(ContentType) == 0 && outLinebyte[0] == 45) 
break; 
fileoutputstream.write(Linebyte, 0, ai[0]); 
fileoutputstream.flush(); 
} 

byte byte0; 
if(newline.length() == 1) 
byte0 = 2; 
else 
byte0 = 1; 
if(s5 != null && outLinebyte[0] != 45 && ai1[0] > newline.length() * byte0) 
fileoutputstream.write(outLinebyte, 0, ai1[0] - newline.length() * byte0); 
if(sContentType != null && Linebyte[0] != 45 && ai[0] > newline.length() * byte0) 
fileoutputstream.write(Linebyte, 0, ai[0] - newline.length() * byte0); 

fileoutputstream.close(); 
} 
} 

private String readLine(byte Linebyte[], int ai[], 
ServletInputStream servletinputstream, 
String CharacterEncoding){ 
try{ 
//readLine(byte[] buffer, int offset, int length) 
//Reads a line from the POST data. 
ai[0] = servletinputstream.readLine(Linebyte, 0, Linebyte.length); 
if(ai[0] == -1) 
return null; 
}catch(IOException _ex){ 
return null; 
} 
try{ 
if(CharacterEncoding == null){ 
//用缺省的编码方式把给定的byte数组转换为字符串 
//String(byte[] bytes, int offset, int length) 
return new String(Linebyte, 0, ai[0]); 
}else{ 
//用给定的编码方式把给定的byte数组转换为字符串 
//String(byte[] bytes, int offset, int length, String enc) 
return new String(Linebyte, 0, ai[0], CharacterEncoding); 
} 
}catch(Exception _ex){ 
return null; 
} 
} 
/* 
public int readLine(byte[] buffer, 
int offset, 
int length) throws java.io.IOException 
从POST来的数据中读一行 
参数: 
buffer - buffer to hold the line data 
offset - offset into the buffer to start 
length - maximum number of bytes to read. 
Returns: 
number of bytes read or -1 on the end of line. 
*/ 
} 

<淘宝热门商品:
 

2.35 元  

露连泉百货超级市场

阿尔卑斯喜缘喜糖 全市最低价

 

128.00 元  

【广州商盟】*大学生淘宝皇冠第一店-鞋神--三人行出口剩余旗舰店

【大学生皇冠店】new balance纽巴伦378经典款 天蓝


来源:程序员网

小小豆叮

信息系统建模方法

周中元 我有话说……    大型信息系统通常十分复杂,很难直接对它进行分析设计,人们经常借助模型来设计分析系统。模型是现实世界中的某些事物的一种抽象表示。抽象的含义是抽取事物的本质特性,忽略事物的其他次要因素。因此,模型既反映事物的原型,又不等于该原型。模型是理解、分析、开发或改造事物原型的一种常用手段。例如,建造大楼前常先做大楼的模型,以便在大楼动工前就能使人们对未来的大楼有一个十分清晰的感性认识,显然,大楼模型还可以用来改进大楼的设计方案。   在信息系统中,模型是开发过程中的一个不可缺少的工具。信息系统包括数据处理、事务管理和决策支持。实质上,信息系统可以看成是由一系列有序的模型构成的,这些有序模型通常为:功能模型、信息模型、数据模型、控制模型和决策模型,所谓有序是指这些模型上分别在系统的不同开发阶段、不同开发层次上建立的。 信息建模方法介绍   模型的表示形式可以是数学公式、缩小的物理装置、图表文字说明,也可以是专用的形式化语言。模型建立的思路有两种:自顶向下、逐步求精和自底向上、综合集成。   模型的目标即模型研究的目的,知识是指现实系统的知识和模型构造知识,数据是指系统的原始信息,这三方面构成了建模过程的输入。模型构造是具体的建模技术的运用过程。可信性分析是指分析所建模型能否满足系统目标。   信息系统模型的表现形式与普通系统模型是有区别的。描述信息系统模型最常见的方法是形式化描述和图示化描述。形式化描述方法非常精确、严谨,易于系统以后的实现,但难以掌握和理解,模型可读性差,往往只有专业人员才会使用,因而难于推广。图示化方法直观、自然,易于描述系统的层次结构、功能组成,且简单易学,通常还有工具软件支持,因而成为信息系统的主要描述工具,但这种方法的精确性和严谨性不够。   信息系统的建模方法可以分为:面向过程的建模、面向数据的建模、面向信息的建模、面向决策的建模和面向对象的建模五种。   面向过程的建模方法是把过程看作系统模型的基本部分,数据是随着过程而产生的。最有影响的面向过程的设计方法是Yourdon设计法。   面向数据的建模方法把模型的输入输出看成是最为重要的,因此,首先定义的是数据结构,而过程模块是从数据结构中导出的,即功能跟随数据。最有影响的面向数据的设计方法是Jackson设计法。   面向信息的建模方法与面向数据建模方法的区别就是信息和数据的区别。信息和数据都是信息系统中最基本的术语,数据是指记载下来的事实,是客观实体属性的值,而信息是构成一定含义的一组数据。面向信息建模方法是从整个系统的逻辑数据模型开始的,通过一个全局信息需求视图来说明系统中所有基本数据实体及其相互关系,然后,在此基础上逐步构造整个模型,信息模型记录系统运作所需的信息实体,如:人员,地点,事物,观念等,为分析现行系统提供信息的图形化表示。数据建模的目的是设计和实现满足系统信息需求的数据库结构,即数据建模支持系统设计。   决策支持系统由数据库、模型库和各自的管理系统组成。决策支持系统模型需要反映的问题是系统的决策制订原则和机理、系统的组织机构和人员配置。通过对决策系统的建模,企业的领导可以对企业有一个细致的了解,从而发现其中问题。如组织结构臃肿,职权划分不清,权力范围不合理等,据此进行相应的改革。比较成熟的决策支持系统建模方法有Petri网和GRAI法。   面向对象的分析方法是利用面向对象的信息建模概念,如实体、关系、属性等,同时运用封装、继承、多态等机制来构造模拟现实系统的方法。传统的结构化设计方法的基本点是面向过程,系统被分解成若干个过程。而面向对象的方法是采用构造模型的观点,在系统的开发过程中,各个步骤的共同的目标是建造一个问题域的模型。在面向对象的设计中,初始元素是对象,然后将具有共同特征的对象归纳成类,组织类之间的等级关系,构造类库。在应用时,在类库中选择相应的类。 IDEF方法族介绍   IDEF的含义是集成计算机辅助制造(Integrated Computer-AidedManufacturing,ICAM)DEFinition。最初的IDEF方法是在美国空军ICAM项目建立的,最初开发3种方法:功能建模(IDEF0)、信息建模(IDEF1)、动态建模(IDEF2),后来,随着信息系统的相继开发,又开发出了下列IDEF族方法:数据建模(IDEF1X)、过程描述获取方法(IDEF3)、面向对象的设计(OO设计)方法(IDEF4)、使用C++语言的OO设计方法(IDEF4C++)、实体描述获取方法(IDEF5)、设计理论(rationale)获取方法(IDEF6)、人-系统交互设计方法(IDEF8)、业务约束发现方法(IDEF9)、网络设计方法(IDEF14)等。根据用途,可以把IDEF族方法分成两类:   第一类IDEF方法的作用是沟通系统集成人员之间的信息交流。主要有:IDEF0、IDEF1、IDEF3、IDEF5。IDEF0通过对功能的分解、功能之间关系的分类(如按照输入、输出、控制和机制分类)来描述系统功能。IDEF1用来描述企业运作过程中的重要信息。IDEF3支持系统用户视图的结构化描述。IDEF5用来采集事实和获取知识。   第二类IDEF方法的重点是系统开发过程中的设计部分。目前有两种IDEF设计方法:IDEF1X和IDEF4。IDEF1X可以辅助语义数据模型的设计。IDEF4可以产生面向对象实现方法所需的高质量的设计产品。   下面简单介绍几种主要IDEF族方法。 IDEF1信息建模方法   IDEF1方法的作用是在需求分析时对所建系统的信息资源进行分析和交流。IDEF1通常用来:(1)确定组织中当前管理的是什么信息,(2)对需求分析过程中发现的问题确定哪些是由于缺乏合适的信息引起的,(3)指定在TO-BE实施中,哪些信息需要管理。   从IDEF1的角度看信息系统,它不但包括自动化系统的成分,也包括非自动化的成分,如人员,文件柜,电话等等。与数据库设计方法不同,IDEF1是分析以下问题的一种方法:   企业信息的采集、存储和管理;   信息的管理规则;   企业内信息之间的逻辑关系;   缺乏良好的信息管理导致的问题。   IDEF1使用简单的图形约定来表达复杂的规则集合。这些规则有助于建模者区分(1)现实世界的对象,(2)现实世界对象之间的物理或抽象的联系,(3)现实世界对象的信息管理,(4)用来表示信息的需求、应用和管理的数据结构。IDEF1的目标之一就是为信息分析提供一个结构化的、规程化的方法。IDEF1可以减少建模过程中的不完整性、不精确性、不一致性和不准确性。   IDEF1是描述企业信息需求的一个有效方法。IDEF1建模奠定了数据库设计基础,给出了信息结构定义,提供了反映基本信息需求的需求说明。IDEF1使用规程化的、结构化的技术以找出一个组织所使用的信息和业务规则。IDEF1要求信息用户积极参与,使用户认真思考信息如何使用和管理。最后,信息模型在企业的整个生命周期均有用的。 IDEF3过程描述获取方法   IDEF3为收集和记录过程提供了一种机制。IDEF3以自然的方式记录状态和事件之间的优先和因果关系,办法是为表达一个系统、过程或组织如何工作的知识提供一种结构化的方法。IDEF3可以:   记录在调研过程中产生的原始数据;   确定信息资源在企业的主要业务流程中的作用;   记录决策过程,特别是关于制造、工程和维修的产   品定义数据的决策过程;   管理数据配置和更改控制策略定义;   进行系统设计和分析;   提供模拟模型。   IDEF3描述现有系统或建议系统的行为方面内容。IDEF3作为描述系统直觉知识的工具,获取的过程知识是结构化的。IDEF3还记录了所有时间性的信息,包括与企业处理过程相关的优先和因果关系。IDEF3描述的结果是为分析和设计模型提供一个结构化的知识库。与构造预测性的数据模型的模拟语言(如SIMAN,SLAM,GPSS,WITNESS)不同,IDEF3构造一个结构化的描述。这些描述获取关于系统实际运作什么或将要做什么,同时提供该系统的不同用户的视图表示。   IDEF3有两种描述方式:过程流和对象状态转变网络。IDEF3过程流描述过程以及过程之间的关系网络,描述"如何做"的知识,如描述一个部位在制造过程中发生的情况。这些过程间的关系是在整个业务流程中产生的,描述的目的是说明事物是如何运作的。 IDEF4面向对象设计方法   在美国空军Armstrong实验室倡导下开发的IDEF4方法可以应用于使用面向对象技术的应用中。IDEF4是由专业的面向对象的设计人员和编程人员开发的,选择IDEF4方法的最重要的原因是它把面向对象的设计看作是大系统开发框架的一部分,而不是把面向对象的设计和分析相隔离。IDEF4强调在面向对象的设计过程中的图形化语法,使用图形化语法和图示有助于对重要的设计事件进行集中和交流。   IDEF4与其他对象设计方法有明显的区别,最主要的是它支持"最小委托(leastcommitment)"策略,支持在类继承、对象组成、功能分解和多态方面的设计评估。   IDEF4把面向对象的设计活动划分成离散的、可管理的大块。每个子活动由一个强调设计决策的图形化语法支持。IDEF4方法很容易让设计者在设计类继承、类组成、功能分解和多态之间作平衡。IDEF4更是一个图形化的语法,它为运用和发展面向对象的设计提供了一个一致的框架,而这一设计最终是由类不变数据清单和方法集约定描述的。   一个IDEF4模型由两个子模型组成:类子模型和方法子模型。两个子模型通过一个调度映射连接。这两个结构描述设计模型中的所有信息。   类子模型由下列类型的图示组成:(1)定义类继承关系的继承图示;(2)定义类组合的类型图示;(3)定义方法调用规约的规约图示;(4)描述对象例示流程的例示图示,这些例示流程有助于设计者对设计进行核查。   方法子模型由下列两个图示类组成:(1)按照行为相似性区分方法类型的方法分类学图示和(2)为功能分解,说明方法的客户和提供者的客户图示。 IDEF5实体论(Ontology)描述获取方法   实体论历史上起源于形而上学这一哲学分支,主要研究客观世界的本质。传统的实体论研究目的是将客观世界进行分割以发现其基本组成成分。自然科学提供了关于实体论研究的一个极好范例。例如,原子物理学将现实世界的物质作了最基本的分类(如质子、电子、中子),生物科学将地球上各种生物进行分类描述。   IDEF5方法是一种具有扎实的理论和实践基础的方法,用于实现实体的建立、修改和维护。该方法所提供的标准化的过程,直观自然的表现能力,高质量的结果,有助于降低开发的成本。   实体分析由三个过程来实现,即用于描述某领域特定对象和过程的词汇集,开发该词汇集中基本术语的定义,刻画术语间的逻辑联系。   实体由三部分组成,它们是某一领域使用的术语集、术语使用规则、推论。在每个领域有很多自然现象,人们用对象(概念的或物理的)、状态和联系加以区别,不同的语言对这些现象有不同的表达方式。在实体论中,"关系"是对客观世界中的联系进行确定的描述,"术语"是对客观世界对象或状态进行确定的描述。   在构造实体时,试图将这些描述进行归类,建立某特定领域的表达模型(比如数据字典)。构造一个实体需要以下三步工作:(1)将术语分类,(2)寻找术语的约束关系,(3)建立模型,该模型能将给定的描述语句变成"恰当"的表达。所谓"恰当"具有两方面的含义,首先,在通常情况下输入一种描述语句可能会产生大量的输出语句,而实体模型只生成在上下文中有用的子集;其次,生成的描述语句表达实际的情况。我们称该模型包含被认可的推理。也可以说模型刻画了对象的行为和该领域的联系。由此看来,实体与数据字典非常相似,所不同的是实体同时包括了语法和领域的行为模型。 <淘宝热门商品:
 

86.00 元  

艾尔微品牌店//九阳豆浆机//女士精品-三钻100%真人拍摄

Disney Mickey 迪斯尼米奇多色手动机芯机械中性手表

 

¥:29.00 

‖ 淘时尚 ‖入托名字条‖布质可烫可缝‖姓名贴‖

‖四钻‖棉质耐洗‖全彩色免缝姓名条 熨烫入托名字条 迪斯尼


来源:程序员网

小小豆叮

面向对象软件的测试

-------------------------------------------------------------------------------- 一 引言(Introduction)   用户使用低质量的软件,在运行过程中会产生各种各样的问题,可能带来不同程度的严重后果,轻者影响系统的正常工作,重者造成事故,损失生命财产。软件测试是保证软件质量的最重要的手段。什么是软件测试?1983年IEEE定义为:使用人工或自动手段来运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差别。   现代的软件开发工程是将整个软件开发过程明确的划分为几个阶段,将复杂问题具体按阶段加以解决。这样,在软件的整个开发过程中,可以对每一阶段提出若干明确的监控点,作为各阶段目标实现的检验标准,从而提高开发过程的可见度和保证开发过程的正确性。经验证明,软件的质量不仅是体现在程序的正确性上,它和编码以前所做的需求分析,软件设计密切相关。软件使用中出现的错误,不一定是编程人员在编码阶段引入的,很可能在程序设计,甚而需求分析时就埋下了祸因。这时,对错误的纠正往往不能通过可能会诱发更多错误的简单的修修补补,而必须追溯到软件开发的最初阶段。这无疑增大了软件的开发费用。因此,为了保证软件的质量,我们应该着眼于整个软件生存期,特别是着眼于编码以前的各开发阶段的工作。这样,软件测试的概念和实施范围必须扩充,应该包括在整个开发各阶段的复查、评估和检测。由此,广义的软件测试实际是由确认、验证、测试三个方面组成(注:本文对后面用广义测试概念处不另加标识):   确认:是评估将要开发的软件产品是否是正确无误、可行和有价值的。比如,将要开发的软件是否会满足用户提出的要求,是否能在将来的实际使用环境中正确稳定的运行,是否存在隐患等。这里包含了对用户需求满足程度的评价。确认意味着确保一个待开发软件是正确无误的,是对软件开发构想的检测。   验证:是检测软件开发的每个阶段、每个步骤的结果是否正确无误,是否与软件开发各阶段的要求或期望的结果相一致。验证意味着确保软件是会正确无误的实现软件的需求,开发过程是沿着正确的方向在进行。   测试:与狭隘的测试概念统一。通常是经过单元测试、集成测试、系统测试三个环节。   在整个软件生存期,确认、验证、测试分别有其侧重的阶段。确认主要体现在计划阶段、需求分析阶段、也会出现在测试阶段;验证主要体现在设计阶段和编码阶段;测试主要体现在编码阶段和测试阶段。事实上,确认、验证、测试是相辅相成的。确认无疑会产生验证和测试的标准,而验证和测试通常又会帮助完成一些确认,特别是在系统测试阶段。   面向对象技术是一种全新的软件开发技术,正逐渐代替被广泛使用的面向过程开发方法,被看成是解决软件危机的新兴技术。面向对象技术产生更好的系统结构,更规范的编程风格,极大的优化了数据使用的安全性,提高了程序代码的重用,一些人就此认为面向对象技术开发出的程序无需进行测试。应该看到,尽管面向对象技术的基本思想保证了软件应该有更高的质量,但实际情况却并非如此,因为无论采用什么样的编程技术,编程人员的错误都是不可避免的,而且由于面向对象技术开发的软件代码重用率高,更需要严格测试,避免错误的繁衍。因此,软件测试并没有面向对象编程的兴起而丧失掉它的重要性。   从1982年在美国北卡罗来纳大学召开首次软件测试的正式技术会议至今,软件测试理论迅速发展,并相应出现了各种软件测试方法,使软件测试技术得到极大的提高。然而,一度实践证明行之有效的软件测试对面向对象技术开发的软件多少显得有些力不从心。尤其是面向对象技术所独有的多态,继承,封装等新特点,产生了传统语言设计所不存在的错误可能性,或者使得传统软件测试中的重点不再显得突出,或者使原来测试经验认为和实践证明的次要方面成为了主要问题。例如:   在传统的面向过程程序中,对于函数   y=Function(x);   你只需要考虑一个函数(Function())的行为特点,而在面向对象程序中,你不得不同时考虑基类函数(Base::Function())的行为和继承类函数(Derived::Function())的行为。   面向对象程序的结构不再是传统的功能模块结构,作为一个整体,原有集成测试所要求的逐步将开发的模块搭建在一起进行测试的方法已成为不可能。而且,面向对象软件抛弃了传统的开发模式,对每个开发阶段都有不同以往的要求和结果,已经不可能用功能细化的观点来检测面向对象分析和设计的结果。因此,传统的测试模型对面向对象软件已经不再适用。针对面向对象软件的开发特点,应该有一种新的测试模型。 二 面向对象测试模型(Object-Orient Test Model)   面向对象的开发模型突破了传统的瀑布模型,将开发分为面向对象分析(OOA),面向对象设计(OOD),和面向对象编程(OOP)三个阶段。分析阶段产生整个问题空间的抽象描述,在此基础上,进一步归纳出适用于面向对象编程语言的类和类结构,最后形成代码。由于面向对象的特点,采用这种开发模型能有效的将分析设计的文本或图表代码化,不断适应用户需求的变动。针对这种开发模型,结合传统的测试步骤的划分,本文建议一种整个软件开发过程中不断测试的测试模型,使开发阶段的测试与编码完成后的单元测试、集成测试、系统测试成为一个整体。测试模型如下图所示:                    0                      面向对象编程        OOA Test:面向对象分析的测试      OOD Test:面向对象设计的测试        OOP Test:面向对象编程的测试      OO Unit Test:面向对象单元测试        OO Integrate Test:面向对象集成测试  OO System Test:面向对象系统测试   OOA Test和OOD Test 是对分析结果和设计结果的测试,主要是对分析设计产生的文本进行,是软件开发前期的关键性测试。OOP Test主要针对编程风格和程序代码实现进行测试,其主要的测试内容在面向对象单元测试和面向对象集成测试中体现。面向对象单元测试是对程序内部具体单一的功能模块的测试,如果程序是用C++语言实现,主要就是对类成员函数的测试。面向对象单元测试是进行面向对象集成测试的基础。面向对象集成测试主要对系统内部的相互服务进行测试,如成员函数间的相互作用,类间的消息传递等。面向对象集成测试不但要基于面向对象单元测试,更要参见OOD或OOD Test结果(详见后叙述)。面向对象系统测试是基于面向对象集成测试的最后阶段的测试,主要以用户需求为测试标准,需要借鉴OOA或OOA Test结果。   尽管上述各阶段的测试构成一相互作用的整体,但其测试的主体、方向和方法各有不同,且为叙述的方便,本文接下来将从OOA,OOD,OOP,单元测试,集成测试,系统测试六个方面分别介绍对面向对象软件的测试。 三 面向对象分析的测试(OOA Test)   传统的面向过程分析是一个功能分解的过程,是把一个系统看成可以分解的功能的集合。这种传统的功能分解分析法的着眼点在于一个系统需要什么样的信息处理方法和过程,以过程的抽象来对待系统的需要。而面向对象分析(OOA)是"把E-R图和语义网络模型,即信息造型中的概念,与面向对象程序设计语言中的重要概念结合在一起而形成的分析方法",最后通常是得到问题空间的图表的形式描述。   OOA直接映射问题空间,全面的将问题空间中实现功能的现实抽象化。将问题空间中的实例抽象为对象(不同于C++中的对象概念),用对象的结构反映问题空间的复杂实例和复杂关系,用属性和服务表示实例的特性和行为。对一个系统而言,与传统分析方法产生的结果相反,行为是相对稳定的,结构是相对不稳定的,这更充分反映了现实的特性。OOA的结果是为后面阶段类的选定和实现,类层次结构的组织和实现提供平台。因此,OOA对问题空间分析抽象的不完整,最终会影响软件的功能实现,导致软件开发后期大量可避免的修补工作;而一些冗余的对象或结构会影响类的选定、程序的整体结构或增加程序员不必要的工作量。因此,本文对OOA的测试重点在其完整性和冗余性。   尽管OOA的测试是一个不可分割的系统过程,为叙述的方便,对OOA阶段的测试划分为以下五个方面:   ☆ 对认定的对象的测试   ☆ 对认定的结构的测试   ☆ 对认定的主题的测试   ☆ 对定义的属性和实例关联的测试   ☆ 对定义的服务和消息关联的测试      1 对认定的对象的测试:   OOA中认定的对象是对问题空间中的结构,其他系统,设备,被记忆的事件,系统涉及的人员等实际实例的抽象(参见[2])。对它的测试可以从如下方面考虑:   1.1 认定的对象是否全面,是否问题空间中所有涉及到的实例都反映在认定的抽象对象中。   1.2 认定的对象是否具有多个属性。只有一个属性的对象通常应看成其他对象的属性,而不是抽象为独立的对象。   1.3 对认定为同一对象的实例是否有共同的,区别于其他实例的共同属性。   1.4 对认定为同一对象的实例是否提供或需要相同的服务,如果服务随着不同的实例而变化,认定的对象就需要分解或利用继承性来分类表示。   1.5 如果系统没有必要始终保持对象代表的实例的信息,提供或者得到关于它的服务,认定的对象也无必要。   1.6 认定的对象的名称应该尽量准确,适用。   2 对认定的结构的测试   在Coad方法中,认定的结构指的是多种对象的组织方式,用来反映问题空间中的复杂实例和复杂关系。认定的结构分为两种:分类结构和组装结构。分类结构体现了问题空间中实例的一般与特殊的关系,组装结构体现了问题空间中实例整体与局部的关系。   2.1 对认定的分类结构的测试可从如下方面着手:     2.1.1 对于结构中的一种对象,尤其是处于高层的对象,是否在问题空间中含有不同于下一层对象的特殊可能性,即是否能派生出下一层对象。     2.1.2 对于结构中的一种对象,尤其是处于同一低层的对象,是否能抽象出在现实中有意义的更一般的上层对象。     2.1.3 对所有认定的对象,是否能在问题空间内向上层抽象出在现实中有意义的对象     2.1.4 高层的对象的特性是否完全体现下层的共性     2.1.5 低层的对象是否有高层特性基础上的特殊性   2.2 对认定的组装结构的测试从如下方面入手:     2.2.1 整体(对象)和部件(对象)的组装关系是否符合现实的关系。     2.2.2 整体(对象)的部件(对象)是否在考虑的问题空间中有实际应用。     2.2.3 整体(对象)中是否遗漏了反映在问题空间中有用的部件(对象)。     2.2.4 部件(对象)是否能够在问题空间中组装新的有现实意义的整体(对象)。   3 对认定的主题的测试   主题是在对象和结构的基础上更高一层的抽象,是为了提供OOA分析结果的可见性,如同文章对各部分内容的概要。对主题层的测试应该考虑以下方面:   3.1 贯彻George Miller 的"7+2"原则,如果主题个数超过7个,就要求对有较密切属性和服务的主题进行归并。   3.2 主题所反映的一组对象和结构是否具有相同和相近的属性和服务。   3.3 认定的主题是否是对象和结构更高层的抽象,是否便于理解OOA结果的概貌(尤其是对非技术人员的OOA 结果读者)。   3.4 主题间的消息联系(抽象)是否代表了主题所反映的对象和结构之间的所有关联。   4 对定义的属性和实例关联的测试   属性是用来描述对象或结构所反映的实例的特性。而实例关联是反映实例集合间的映射关系。对属性和实例关联的测试从如下方面考虑:   4.1 定义的属性是否对相应的对象和分类结构的每个现实实例都适用。   4.2 定义的属性在现实世界是否与这种实例关系密切。   4.3 定义的属性在问题空间是否与这种实例关系密切。   4.4 定义的属性是否能够不依赖于其他属性被独立理解。   4.5 定义的属性在分类结构中的位置是否恰当,低层对象的共有属性是否在上层对象属性体现。   4.6 在问题空间中每个对象的属性是否定义完整。   4.7 定义的实例关联是否符合现实。   4.8 在问题空间中实例关联是否定义完整,特别需要注意1-多和多-多的实例关联。   5 对定义的服务和消息关联的测试   定义的服务,就是定义的每一种对象和结构在问题空间所要求的行为。由于问题空中实例间必要的通信,在OOA 中相应需要定义消息关联(详细内容参见[3])。对定义的服务和消息关联的测试从如下方面进行:   5.1 对象和结构在问题空间的不同状态是否定义了相应的服务。   5.2 对象或结构所需要的服务是否都定义了相应的消息关联。   5.3 定义的消息关联所指引的服务提供是否正确。   5.4 沿着消息关联执行的线程是否合理,是否符合现实过程。   5.5 定义的服务是否重复,是否定义了能够得到的服务。 四 面向对象设计的测试(OOD Test)   通常的结构化的设计方法,用的"是面向作业的设计方法,它把系统分解以后,提出一组作业,这些作业是以过程实现系统的基础构造,把问题域的分析转化为求解域的设计,分析的结果是设计阶段的输入"。   而面向对象设计(OOD)采用"造型的观点",以OOA为基础归纳出类,并建立类结构或进一步构造成类库,实现分析结果对问题空间的抽象。OOD 归纳的类,可以是对象简单的延续,可以是不同对象的相同或相似的服务。由此可见,OOD不是在OOA上的另一思维方式的大动干戈,而是OOA的进一步细化和更高层的抽象。所以,OOD与OOA 的界限通常是难以严格区分的。OOD确定类和类结构不仅是满足当前需求分析的要求,更重要的是通过重新组合或加以适当的补充,能方便实现功能的重用和扩增,以不断适应用户的要求。因此,对OOD的测试,本文建议针对功能的实现和重用以及对OOA结果的拓展,从如下三方面考虑:   ☆ 对认定的类的测试   ☆ 对构造的类层次结构的测试   ☆ 对类库的支持的测试   1 对认定的类的测试   OOD认定的类可以是OOA中认定的对象,也可以是对象所需要的服务的抽象,对象所具有的属性的抽象。认定的类原则上应该尽量基础性,这样才便于维护和重用。测试认定的类:   1.1 是否含盖了OOA中所有认定的对象。   1.2 是否能体现OOA中定义的属性。   1.3 是否能实现OOA中定义的服务。   1.4 是否对应着一个含义明确的数据抽象。   1.5 是否尽可能少的依赖其他类。   1.6 类中的方法(C++:类的成员函数)是否单用途。   2 对构造的类层次结构的测试   为能充分发挥面向对象的继承共享特性,OOD的类层次结构,通常基于OOA中产生的分类结构的原则来组织,着重体现父类和子类间一般性和特殊性。两者概念上的差异。在当前的问题空间,对类层次结构的主要要求是能在解空间构造实现全部功能的结构框架。为此,测试如下方面:   2.1 类层次结构是否含盖了所有定义的类。   2.2 是否能体现OOA中所定义的实例关联。   2.3 是否能实现OOA中所定义的消息关联。   2.4 子类是否具有父类没有的新特性。   2.5 子类间的共同特性是否完全在父类中得以体现。   3 对类库支持的测试   对类库的支持虽然也属于类层次结构的组织问题,但其强调的重点是再次软件开发的重用。由于它并不直接影响当前软件的开发和功能实现,因此,将其单独提出来测试,也可作为对高质量类层次结构的评估。拟订测试点如下:   3.1 一组子类中关于某种含义相同或基本相同的操作,是否有相同的接口(包括名字和参数表)。   3.2 类中方法(C++:类的成员函数)功能是否较单纯,相应的代码行是否较少。   3.3 类的层次结构是否是深度大,宽度小。 五 面向对象编程的测试(OOP Test)   典型的面向对象程序具有继承、封装和多态的新特性,这使得传统的测试策略必须有所改变。封装是对数据的隐藏,外界只能通过被提供的操作来访问或修改数据,这样降低了数据被任意修改和读写的可能性,降低了传统程序中对数据非法操作的测试。继承是面向对象程序的重要特点,继承使得代码的重用率提高,同时也使错误传播的概率提高。继承使得传统测试遇见了这样一个难题:对继承的代码究竟应该怎样测试?(参见面向对象单元测试)。多态使得面向对象程序对外呈现出强大的处理能力,但同时却使得程序内"同一"函数的行为复杂化,测试时不得不考虑不同类型具体执行的代码和产生的行为。   面向对象程序是把功能的实现分布在类中。能正确实现功能的类,通过消息传递来协同实现设计要求的功能。正是这种面向对象程序风格,将出现的错误能精确的确定在某一具体的类。因此,在面向对象编程(OOP)阶段,忽略类功能实现的细则,将测试的目光集中在类功能的实现和相应的面向对象程序风格,主要体现为以下两个方面(假设编程使用C++语言)。   ☆ 数据成员是否满足数据封装的要求   ☆ 类是否实现了要求的功能   1 数据成员是否满足数据封装的要求   数据封装是数据和数据有关的操作的集合。检查数据成员是否满足数据封装的要求,基本原则是数据成员是否被外界(数据成员所属的类或子类以外的调用)直接调用。更直观的说,当改编数据成员的结构时,是否影响了类的对外接口,是否会导致相应外界必须改动。值得注意,有时强制的类型转换会破坏数据的封装特性。例如:   class Hiden   {private:   int a=1;   char *p= "hiden";}   class Visible   {public:   int b=2;   char *s= "visible";}   …..   …..   Hiden pp;   Visible *qq=(Visible *)&pp;   在上面的程序段中,pp的数据成员可以通过qq被随意访问。   2 类是否实现了要求的功能   类所实现的功能,都是通过类的成员函数执行。在测试类的功能实现时,应该首先保证类成员函数的正确性。单独的看待类的成员函数,与面向过程程序中的函数或过程没有本质的区别,几乎所有传统的单元测试中所使用的方法,都可在面向对象的单元测试中使用。具体的测试方法在面向对象的单元测试中介绍。类函数成员的正确行为只是类能够实现要求的功能的基础,类成员函数间的作用和类之间的服务调用是单元测试无法确定的。因此,需要进行面向对象的集成测试。具体的测试方法在面向对象的集成测试中介绍。需要着重声明,测试类的功能,不能仅满足于代码能无错运行或被测试类能提供的功能无错,应该以所做的OOD结果为依据,检测类提供的功能是否满足设计的要求,是否有缺陷。必要时(如通过OOD结仍不清楚明确的地方)还应该参照OOA的结果,以之为最终标准。 六 面向对象的单元测试(OO Unit Test)   传统的单元测试是针对程序的函数、过程或完成某一定功能的程序块。沿用单元测试的概念,实际测试类成员函数。一些传统的测试方法在面向对象的单元测试中都可以使用。如等价类划分法,因果图法,边值分析法,逻辑覆盖法,路径分析法,程序插装法等等,方法的具体实现参见[6]。单元测试一般建议由程序员完成。   用于单元级测试进行的测试分析(提出相应的测试要求)和测试用例(选择适当的输入,达到测试要求),规模和难度等均远小于后面将介绍的对整个系统的测试分析和测试用例,而且强调对语句应该有100%的执行代码覆盖率。在设计测试用例选择输入数据时,可以基于以下两个假设:   1. 如果函数(程序)对某一类输入中的一个数据正确执行,对同类中的其他输入也能正确执行。   2. 如果函数(程序)对某一复杂度的输入正确执行,对更高复杂度的输入也能正确执行。例如需要选择字符串作为输入时,基于本假设,就无须计较于字符串的长度。除非字符串的长度是要求固定的,如IP地址字符串。在面向对象程序中,类成员函数通常都很小,功能单一,函数的间调用频繁,容易出现一些不宜发现的错误。例如:   · if (-1==write (fid, buffer, amount)) error_out(); 该语句没有全面检查write()的返回值,无意中断然假设了只有数据被完全写入和没有写入两种情况。当测试也忽略了数据部分写入的情况,就给程序遗留了隐患。   · 按程序的设计,使用函数strrchr()查找最后的匹配字符,但误程序中写成了函数strchr(),使程序功能实现时查找的是第一个匹配字符。   · 程序中将if (strncmp(str1,str2,strlen(str1)))误写成了if (strncmp(str1,str2,strlen(str2)))。如果测试用例中使用的数据str1和str2长度一样,就无法检测出。   因此,在做测试分析和设计测试用例时,应该注意面向对象程序的这个特点,仔细的进行测试分析和设计测试用例,尤其是针对以函数返回值作为条件判断选择,字符串操作等情况。   面向对象编程的特性使得对成员函数的测试,又不完全等同于传统的函数或过程测试。尤其是继承特性和多态特性,使子类继承或过载的父类成员函数出现了传统测试中未遇见的问题。在[7]中,Brian Marick 给出了二方面的考虑:   1. 继承的成员函数是否都不需要测试?   根据[7]中的论述,对父类中已经测试过的成员函数,两种情况需要在子类中重新测试:a)继承的成员函数在子类中做了改动;b)成员函数调用了改动过的成员函数的部分。例如:   假设父类Bass有两个成员函数:Inherited()和Redefined(),子类Derived只对Redefined()做了改动。   Derived::Redefined()显然需要重新测试。对于Derived::Inherited(),如果它有调用Redefined()的语句(如:x=x/Redefined()),就需要重新测试,反之,无此必要。   2. 对父类的测试是否能照搬到子类?   援用上面的假设,Base::Redefined()和Derived::Redefined()已经是不同的成员函数,它们有不同的服务说明和执行。对此,照理应该对 Derived::Redefined()重新测试分析,设计测试用例。但由于面向对象的继承使得两个函数有相似,故只需在 Base::Redefined()的测试要求和测试用例上添加对Derived::Redfined()新的测试要求和增补相应的测试用例。例如:   Base::Redefined()含有如下语句   If (value<0) message ("less");   else if (value==0) message ("equal");   else message ("more");   Derived::Redfined()中定义为   If (value<0) message ("less");   else if (value==0) message ("It is equal");   else   {message ("more");   if (value==88)message("luck");}   在原有的测试上,对Derived::Redfined()的测试只需做如下改动:将value==0的测试结果期望改动;增加value==88的测试。   多态有几种不同的形式,如参数多态,包含多态,过载多态。包含多态和过载多态在面向对象语言中通常体现在子类与父类的继承关系,对这两种多态的测试参见上述对父类成员函数继承和过载的论述。包含多态虽然使成员函数的参数可有多种类型,但通常只是增加了测试的繁杂。对具有包含多态的成员函数测试时,只需要在原有的测试分析和基础上扩大测试用例中输入数据的类型的考虑。对类为粒度进行面向对象的单元测试,可参考[10]中关于如何从MtSS生成测试用例的说明。 七 面向对象的集成测试(OO Integrate Test)     传统的集成测试,是由底向上通过集成完成的功能模块进行测试,一般可以在部分程序编译完成的情况下进行。而对于面向对象程序,相互调用的功能是散布在程序的不同类中,类通过消息相互作用申请和提供服务。类的行为与它的状态密切相关,状态不仅仅是体现在类数据成员的值,也许还包括其他类中的状态信息。由此可见,类相互依赖极其紧密,根本无法在编译不完全的程序上对类进行测试。所以,面向对象的集成测试通常需要在整个程序编译完成后进行。此外,面向对象程序具有动态特性,程序的控制流往往无法确定,因此也只能对整个编译后的程序做基于黑盒子的集成测试。   面向对象的集成测试能够检测出相对独立的单元测试无法检测出的那些类相互作用时才会产生的错误。基于单元测试对成员函数行为正确性的保证,集成测试只关注于系统的结构和内部的相互作用。面向对象的集成测试可以分成两步进行:先进行静态测试,再进行动态测试。   静态测试主要针对程序的结构进行,检测程序结构是否符合设计要求。现在流行的一些测试软件都能提供一种称为"可逆性工程"的功能,即通过原程序得到类关系图和函数功能调用关系图,例如International Software Automation 公司的Panorama-2 forWindows95、Rational公司的Rose C++ Analyzer等,将"可逆性工程"得到的结果与OOD的结果相比较,检测程序结构和实现上是否有缺陷。换句话说,通过这种方法检测OOP是否达到了设计要求。   动态测试设计测试用例时,通常需要上述的功能调用结构图、类关系图或者实体关系图为参考,确定不需要被重复测试的部分,从而优化测试用例,减少测试工作量,使得进行的测试能够达到一定覆盖标准。测试所要达到的覆盖标准可以是:达到类所有的服务要求或服务提供的一定覆盖率;依据类间传递的消息,达到对所有执行线程的一定覆盖率;达到类的所有状态的一定覆盖率等。同时也可以考虑使用现有的一些测试工具 来得到程序代码执行的覆盖率。   具体设计测试用例,可参考下列步骤:   1. 先选定检测的类,参考OOD分析结果,仔细出类的状态和相应的行为,类或成员函数间传递的消息,输入或输出的界定等。   2. 确定覆盖标准。   3. 利用结构关系图确定待测类的所有关联。   4. 根据程序中类的对象构造测试用例,确认使用什么输入激发类的状态、使用类的服务和期望产生什么行为等。   值得注意,设计测试用例时,不但要设计确认类功能满足的输入,还应该有意识的设计一些被禁止的例子,确认类是否有不合法的行为产生,如发送与类状态不相适应的消息,要求不相适应的服务等。根据具体情况,动态的集成测试,有时也可以通过系统测试完成。 八 面向对象的系统测试(OO System Test)   通过单元测试和集成测试,仅能保证软件开发的功能得以实现。但不能确认在实际运行时,它是否满足用户的需要,是否大量存在实际使用条件下会被诱发产生错误的隐患。为此,对完成开发的软件必须经过规范的系统测试。换个角度说,开发完成的软件仅仅是实际投入使用系统的一个组成部分,需要测试它与系统其他部分配套运行的表现,以保证在系统各部分协调工作的环境下也能正常工作。在后面对ZXM10收发台系统测试的叙述可以看到,其他的系统设备(如监控台,图象台,E1接入设备,摄像头等)如何配合收发台的系统测试。   系统测试应该尽量搭建与用户实际使用环境相同的测试平台,应该保证被测系统的完整性,对临时没有的系统设备部件,也应有相应的模拟手段。系统测试时,应该参考OOA分析的结果,对应描述的对象、属性和各种服务,检测软件是否能够完全"再现"问题空间。系统测试不仅是检测软件的整体行为表现,从另一个侧面看,也是对软件开发设计的再确认。   这里说的系统测试是对测试步骤的抽象描述。它体现的具体测试内容包括:   · 功能测试:测试是否满足开发要求,是否能够提供设计所描述的功能,是否用户的需求都得到满足。功能测试是系统测试最常用和必须的测试,通常还会以正式的软件说明书为测试标准。   · 强度测试:测试系统的能力最高实际限度,即软件在一些超负荷的情况,功能实现情况。如要求软件某一行为的大量重复、输入大量的数据或大数值数据、对数据库大量复杂的查询等。   · 性能测试:测试软件的运行性能。这种测试常常与强度测试结合进行,需要事先对被测软件提出性能指标,如传输连接的最长时限、传输的错误率、计算的精度、记录的精度、响应的时限和恢复时限等。   · 安全测试:验证安装在系统内的保护机构确实能够对系统进行保护,使之不受各种非常的干扰。安全测试时需要设计一些测试用例试图突破系统的安全保密措施,检验系统是否有安全保密的漏洞。   · 恢复测试:采用人工的干扰使软件出错,中断使用,检测系统的恢复能力,特别是通讯系统。恢复测试时,应该参考性能测试的相关测试指标。   · 可用性测试:测试用户是否能够满意使用。具体体现为操作是否方便,用户界面是否友好等。   · 安装/卸载测试(install/uninstall test)等等。   系统测试需要对被测的软件结合需求分析做仔细的测试分析,建立测试用例。 <淘宝热门商品:
 

保健品/滋补品 

淑芳阁_苗条姿_最有效的减肥瘦身与丰胸专卖店

 

5.00 元 

超人气面膜 平民价格 顶级效果


来源:程序员网

小小豆叮