关于作者

用户名:太阳鱼
笔名:太阳鱼
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

快速通道

在线留言



个人小区

朋友家园

访问统计:
文章个数:7
评论个数:4
留言条数:0




Powered by BlogDriver 2.1

天天向上——学习篇

 

年轻没有什么不可以!

文章

[转]Java视线论坛 阅读主题 - 面向对象的思维方法
面向对象的思维方法

作者:范凯


我是从学习Java编程开始接触OOP(面向对象编程),刚开始使用Java编写程序的时候感觉很别扭,因为我早以习惯用C来编写程序,很欣赏C的简洁性和高效性,喜欢C简练而表达能力丰富的风格,特别忍受不了Java运行起来慢吞吞的速度,相对冗长的代码,而且一个很简单的事情,要写好多类,一个类调用一个类,心里的抵触情绪很强。

我对Java的面向对象的特性琢磨良久,自认为有所领悟,也开始有意识的运用OOP风格来写程序,然而还是经常会觉得不知道应该怎样提炼类,面对一个具体的问题的时候,会觉得脑子里千头万绪的,不知道怎么下手,一不小心,又会回到原来的思路上去。

举个例子,要发广告邮件,广告邮件列表存在数据库里面。倘若用C来写的话,一般会这样思考,先把邮件内容读入,然后连接数据库,循环取邮件地址,调用本机的qmail的sendmail命令发送。

然后考虑用Java来实现,既然是OOP,就不能什么代码都塞到main过程里面,于是就设计了三个类:

一个类是负责读取数据库,取邮件地址,调用qmail的sendmail命令发送;
一个类是读邮件内容,MIME编码成HTML格式的,再加上邮件头;
一个主类负责从命令读参数,处理命令行参数,调用发email的类。

把一件工作按照功能划分为3个模块分别处理,每个类完成一件模块任务。

仔细的分析一下,就会发现这样的设计完全是从程序员实现程序功能的角度来设计的,或者说,设计类的时候,是自低向上的,从机器的角度到现实世界的角度来分析问题的。因此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的出发点来达到满足现实世界的软件需求的目标。

这样的分析方法其实是不适用于Java这样面向对象的编程语言,因为,如果改用C语言,封装两个C函数,都会比Java实现起来轻松的多,逻辑上也清楚的多。

我觉得面向对象的精髓在于考虑问题的思路是从现实世界的人类思维习惯出发的,只要领会了这一点,就领会了面向对象的思维方法。

举一个非常简单的例子:假使现在需要写一个网页计数器,客户访问一次页面,网页计数器加1,计数器是这样来访问的

java代码: 

http://hostname/count.cgi?id=xxx



后台有一个数据库表,保存每个id(一个id对应一个被统计访问次数的页面)的计数器当前值,请求页面一次,对应id的计数器的字段加1(这里我们忽略并发更新数据库表,出现的表锁定的问题)。

如果按照一般从程序实现的角度来分析,我们会这样考虑:首先是从HTTP GET请求取到id,然后按照id查数据库表,获得某id对应的访问计数值,然后加1,更新数据库,最后向页面显示访问计数。

现在假设一个没有程序设计经验的人,他会怎样来思考这个问题的呢?他会提出什么样的需求呢?他很可能会这样想:

我需要有一个计数器,这个计数器应该有这样的功能,刷新一次页面,访问量就会加1,另外最好还有一个计数器清0的功能,当然计数器如果有一个可以设为任意值的功能的话,我就可以作弊了。

做为一个没有程序设计经验的人来说,他完全不会想到对数据库应该如何操作,对于HTTP变量该如何传递,他考虑问题的角度就是我有什么需求,我的业务逻辑是什么,软件应该有什么功能。

按照这样的思路(请注意,他的思路其实就是我们平时在生活中习惯的思维方式),我们知道需要有一个计数器类 Counter,有一个必须的和两个可选的方法:

java代码: 

getCount()   // 取计数器值方法
resetCounter()   // 计数器清0方法
setCount()   // 设计数器为相应的值方法



把Counter类完整的定义如下:

java代码: 

public class Counter {
  public int getCount(int id) {}
  public void resetCounter(int id) {}
  public void setCount(int id, int currentCount) {}
}



解决问题的框架已经有了,来看一下如何使用Counter。 在count.cgi里面调用Counter来计数,程序片断如下:

java代码: 

  //  这里从HTTP环境里面取id值
   ...
  Counter myCounter = new Counter()// 获得计数器
  int currentCount = myCounter.getCount(id)// 从计数器中取计数
  //  这里向客户浏览器输出
   ...



程序的框架全都写好了,剩下的就是实现Counter类方法里面具体的代码了,此时才去考虑具体的程序语言实现的细节,比如,在getCount()方法里面访问数据库,更新计数值。

从上面的例子中看到,面向对象的思维方法其实就是我们在现实生活中习惯的思维方式,是从人类考虑问题的角度出发,把人类解决问题的思维方式逐步翻译成程序能够理解的思维方式的过程,在这个翻译的过程中,软件也就逐步被设计好了。

在运用面向对象的思维方法进行软件设计的过程中,最容易犯的错误就是开始分析的时候,就想到了程序代码实现的细节,因此封装的类完全是基于程序实现逻辑,而不是基于解决问题的业务逻辑。

学习JDBC编程的经典错误问法是:"我怎样封装对数据库的select操作?"

面向对象的设计是基于解决业务问题的设计,而不是基于具体编程技术的设计。我不会去封装select语句的,我只封装解决问题的业务逻辑,对数据库的读取是在业务逻辑的编码实现阶段才去考虑的问题。

回过头看上面那个发广告邮件的例子,应该如何应用面向对象的思维方法呢?

对于一个邮件来说,有邮件头,邮件体,和邮件地址这三个属性,发送邮件,需要一个发送的方法,另外还需要一个能把所有邮件地址列出来的方法。所以应该如下设计:

java代码: 

类JunkMail

属性:
  head
  body
  address
方法:
  sendMail()    // 发送邮件
  listAllMail() // 列邮件地址

用Java来表示:

public class JunkMail {
  private String head;
  private String body;
  private String address;
  public JunkMain() {   // 默认的类构造器
     // 从外部配置文件读邮件头º陀始å
     this.head=...;
     this.body=...;
  }

  public static boolean sendMail(String address) {
     //  调用qmail,发送email
  }

  public static Collection listAllMail() {
     //  ·梦适菘â,返回一个邮件地址集合
  }
}


当把JunkMail设计好了以后,再调用JunkMail类完成邮件的发送,将是非常轻松的事情。

如果说传统的面向过程的编程是符合机器运行指令的流程的话,那么面向对象的思维方法就是符合现实生活中人类解决问题的思维过程。

在面向对象的软件分析和设计的时候,要提醒自己,不要一上来就去想程序代码的实现,应该抛开具体编程语言的束缚,集中精力分析我们要实现的软件的业务逻辑,分析软件的业务流程,思考应该如何去描述和实现软件的业务。毕竟软件只是一个载体,业务才是我们真正要实现的目标。

但是在设计过程中,心里却往往在担心,如果我完全不去考虑程序代码的实现的话,那么我怎么知道我的设计一定合理呢?我怎么知道我设计的类、接口一定可以实现呢?所以经常可以看到的现象就是:

在设计过程中,虽然知道不能过早考虑代码实现,但是每设计一个类,一个接口,心里都要不知不觉的用自己熟悉的编程语言大概的评估一下,看看能否编出来,因此,一不小心,就会又回到按照程序功能实现的思路进行设计的老路上去了。

举个例子来说明,在做Web程序设计的时候,经常要遇到分页显示数据的情况。比如说需要把系统中所有的用户都列出来这样的功能。假设使用User类来表示用户,增加用户addUser(),删除用户deleteUser(),查询所有用户listUsers()方法。而数据库中有一个user表,一条记录是一个用户的信息。下面考虑一下User类的方法的实现:

addUser()和deleteUser()方法都好实现,就是对数据库增加记录和删除记录。对于listUsers()方法,其实就是对user表的select,取出一个记录集。但是该怎么从listUsers()方法中得到所有用户的列表呢?

一个方法调用的返回值只有一个,没有多个,所以很多情况下采用的办法就是返回值定义为集合类型,比如Vector。这样就可以在listUsers()方法的具体代码实现的时候,从数据库依次取出一个个记录,插入到Vector里面来。在主程序里面,调用listUsers()方法可以返回一个Vector,然后再对Vector遍历操作,就可以得到用户列表了。
java代码: 


public class User {

  public static void addUser(...) {
    //  数据库insert一条记录
  }

  public static void deleteUser(...) {
    //  数据库delete一条记录
  }

  public Vector listUsers(...) {
    //  数据库select结果放到一个集合里面
  }
}

这样的设计基本合理,但是仍然有点小问题。因为在设计的时候,就考虑到了用Java的集合类Vector来实现对不定长数据集的存放,因而违反了面向对象设计的一个原则:在设计的时候不应过早的考虑具体程序语言的实现。所以必须用抽象的方法,和具体实现无关的方法来表达业务逻辑。

我们知道,通常对具有集合特征的数据结构进行遍历通常可以使用next和hasNext方法,next实现取下一个用户,hasNext判断是否还有元素。 因此我们定义一个接口Iterator,这个接口中定义两个方法next和hasNext:
java代码: 


public interface Iterator {
  public boolean hasNext() {}
  public Object next()  {}
}


而User类的listUses方法返回值改为Iterator接口的实现类:

java代码: 

public class User {
  ...
  public Iterator listUsers() {
  }
  ...
}


这样就把User类的设计和具体的实现方法分离开了,因为此时任何实现了next()和hasNext()方法的类都可以做为listUsers的返回值,都可以被用来表达"用户列表",而不仅仅可以使用Vector而已。比如,我可以用ArrayList来表达用户列表,因为ArrayList也实现了Iterator,当然我也可以自己专门写一个类来存放用户列表,只要实现next()和hasNext()方法就行了。

这样在具体的编写代码的时候,程序员具有了最大的灵活性,可以根据具体的情况,采用不同的编程方法来存放用户列表。特别是降低了程序的耦合度,提高了程序的可移植性。对于上面那个JunkMail的listAllMail()方法也同样应该改为接口类型。

然后,在主程序里面就这样来使用User类的listUsers方法:
java代码: 


User myUser = new User();
Iterator iterator = myUser.listUsers();
while (iterator.hasNext()) {
  iterator.next();
}


这样就可以完全不用考虑程序代码实现了,从高层次上把功能抽象出来,定义成为接口,同时又可以把系统设计的很合理,完全根据业务的需求来进行设计。

结语

通过上面的几个例子的设计说明,使用面向对象的思维方法,其实是一个把业务逻辑从具体的编程技术当中抽象出来的过程,而这个抽象的过程是自上而下的,非常符合人类的思维习惯,也就是先不考虑问题解决的细节,把问题的最主要的方面抽象成为一个简单的框架,集中精力思考如何解决主要矛盾,然后在解决问题的过程中,再把问题的细节分割成一个一个小问题,再专门去解决细节问题。

因而一旦牢牢的抓住了这一点,你就会发现在软件设计和开发过程中,你自己总是会不知不觉的运用面向对象的思维方法来设计和编写程序,并且程序的设计和开发也变得不再那么枯燥,而一个合理运用面向对象技术进行设计和架构的软件,更是具备了思维的艺术美感。

最后,愿面向对象的思维方法也能给您的程序设计之路带来创作的乐趣。

- 作者: 太阳鱼 2005年01月25日, 星期二 08:22  回复(1) |  引用(0) 加入博采

java基础的学习

抽象类、接口、工厂的学习......

待续......


- 作者: 太阳鱼 2005年01月24日, 星期一 13:29  回复(0) |  引用(0) 加入博采

window.open详解 (转摘)
【1、最基本的弹出窗口代码】 其实代码非常简单: <SCRIPT LANGUAGE="javascript"> <!-- window.open ('page.html') --> </SCRIPT> 因为这是一段javascripts代码,所以它们应该放在<SCRIPT LANGUAGE="javascript ">标签和</script>之间。<!-- 和 -->是对一些版本低的浏览器起作用,在这些老浏 览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。 window.open ('page.html') 用于控制弹出新的窗口page.html,如果page.html不与主窗口在同一路径下,前面 应写明路径,绝对路径(http://和相对路径(.. /)均可。 用单引号和双引号都可以 ,只是不要混用。 这一段代码可以加入HTML的任意位置,<head>和</head>之间可以,<body>间</body >也可以,越前越早执行,尤其是页面代码长,又想使页面早点弹出就尽量往前放。


【2、经过设置后的弹出窗口】 下面再说一说弹出窗口的设置。只要再往上面的代码中加一点东西就可以了。 我们 来定制这个弹出的窗口的外观,尺寸大小,弹出的位置以适应页面的具体情况。 <SCRIPT LANGUAGE="javascript"> <!-- window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, lef t=0, toolbar=no, menubar=no, scrollbars=no,resizable=no,location=no, statu s=no') //写成一行 --> </SCRIPT> 参数解释: <SCRIPT LANGUAGE="javascript"> js脚本开始; window.open 弹出新窗口的命令; 'page.html' 弹出窗口的文件名; 'newwindow' 弹出窗口的名字(不是文件名),非必须,可用空''代替; height=100 窗口高度; width=400 窗口宽度; top=0 窗口距离屏幕上方的象素值; left=0 窗口距离屏幕左侧的象素值; toolbar=no 是否显示工具栏,yes为显示; menubar,scrollbars 表示菜单栏和滚动栏。 resizable=no 是否允许改变窗口大小,yes为允许; location=no 是否显示地址栏,yes为允许; status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许; </SCRIPT> js脚本结束

【3、用函数控制弹出窗口】 下面是一个完整的代码。 <html> <head> <script LANGUAGE="JavaScript"> <!-- function openwin() { window.open ("page.html", "newwindow", "height=100, width=400, toolbar=no , menubar=no, scrollbars=no, resizable=no, location=no, status=no") //写成一行 } //--> </script> </head> <body onload="openwin()"> ...任意的页面内容... </body> </html> 这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任 何用途。怎么调用呢? 方法一:<body onload="openwin()"> 浏览器读页面时弹出窗口; 方法二:<body onunload="openwin()"> 浏览器离开页面时弹出窗口; 方法三:用一个连接调用: <a href="#" onClick="openwin()">打开一个窗口 </a>注意:使用的"#"是虚连 接。 方法四:用一个按钮调用: <input type="button" onclick="openwin()" value="打开窗口">

【4、同时弹出2个窗口】 对源代码稍微改动一下: <script LANGUAGE="JavaScript"> <!-- function openwin() { window.open ("page.html", "newwindow", "height=100, width=100, top=0, lef t=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, stat us=no") //写成一行 window.open ("page2.html", "newwindow2", "height=100, width=100, top=100, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no , status=no") //写成一行 } //--> </script> 为避免弹出的2个窗口覆盖,用top和left控制一下弹出的位置不要相互覆盖即可。 最后用上面说过的四种方法调用即可。 注意:2个窗口的name(newwindows和newwindow2)不要相同,或者干脆全部为空。 OK?

【5、主窗口打开文件1.htm,同时弹出小窗口page.html】 如下代码加入主窗口<head>区: <script language="javascript"> <!-- function openwin() { window.open("page.html","","width=200,height=200") } //--> </script> 加入<body>区: open即可。

【6、弹出的窗口之定时关闭控制】 下面我们再对弹出的窗口进行一些控制,效果就更好了。如果我们再将一小段代码 加入弹出的页面(注意是加入到page.html的HTML中,可不是主页面中,否则 ...),让 它10秒后自动关闭是不是更酷了? 首先,将如下代码加入page.html文件的<head>区: <script language="JavaScript"> function closeit() { setTimeout("self.close()",10000) //毫秒 } </script> 然后,再用<body onload="closeit()"> 这一句话代替page.html中原有的<BODY>这 一句就可以了。(这一句话千万不要忘记写啊!这一句的作用是调用关闭窗口的代码 ,10秒钟后就自行关闭该窗口。)

【7、在弹出窗口中加上一个关闭按钮】 <FORM> <INPUT TYPE='BUTTON' VALUE='关闭' onClick='window.close()'> </FORM> 呵呵,现在更加完美了!

【8、内包含的弹出窗口-一个页面两个窗口】 上面的例子都包含两个窗口,一个是主窗口,另一个是弹出的小窗口。 通过下面的 例子,你可以在一个页面内完成上面的效果。 <html> <head> <SCRIPT LANGUAGE="JavaScript"> function openwin() { OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no,sc rollbars="+scroll+",menubar=no"); //写成一行 OpenWindow.document.write("<TITLE>例子</TITLE>") OpenWindow.document.write("<BODY BGCOLOR=#ffffff>") OpenWindow.document.write("<h1>Hello!</h1>") OpenWindow.document.write("New window opened!") OpenWindow.document.write("</BODY>") OpenWindow.document.write("</HTML>") OpenWindow.document.close() } </SCRIPT> </head> <body> 打开一个窗口 <input type="button" onclick="openwin()" value="打开窗口"> </body> </html> 看看 OpenWindow.document.write()里面的代码不就是标准的HTML吗?只要按照格 式写更多的行即可。千万注意多一个标签或少一个标签就会出现错误。记得用OpenWin dow.document.close()结束啊。

【9、终极应用--弹出的窗口之Cookie控制】 回想一下,上面的弹出窗口虽然酷,但是有一点小毛病(沉浸在喜悦之中,一定没有 发现吧?)比如你将上面的脚本放在一个需要频繁经过的页面里(例如首页), 那么每 次刷新这个页面,窗口都会弹出一次,是不是非常烦人?:-( 有解决的办法吗?Yes! ;-) Follow me. 我们使用cookie来控制一下就可以了。 首先,将如下代码加入主页面HTML的<HEAD>区: <script> function openwin(){ window.open("page.html","","width=200,height=200") } function get_cookie(Name) { var search = Name + "=" var returnvalue = ""; if (document.cookie.length > 0) { offset = document.cookie.indexOf(search) if (offset != -1) { offset += search.length end = document.cookie.indexOf(";", offset); if (end == -1) end = document.cookie.length; returnvalue=unescape(document.cookie.substring(offset, end)) } } return returnvalue; } function loadpopup(){ if (get_cookie('popped')==''){ openwin() document.cookie="popped=yes" } } </script> 然后,用<body onload="loadpopup()">(注意不是openwin而是loadpop啊!) 替 换主页面中原有的<BODY>这一句即可。你可以试着刷新一下这个页面或重新进入该页 面,窗口再也不会弹出了。真正的Pop-Only-Once! 写到这里弹出窗口的制作和应用技巧基本上算是完成了

- 作者: 太阳鱼 2004年12月3日, 星期五 14:52  回复(0) |  引用(0) 加入博采

Struts Validator

http://www-900.ibm.com/developerworks/cn/wsdd/library/techarticles/0311_fung_yu/fung_yu2.shtml#download

http://www-900.ibm.com/developerworks/cn/wsdd/library/techarticles/0311_fung_yu/fung_yu2.shtml#download

上面的材料中介绍了Struts 验证器,举例分别介绍了使用服务器端验证和使用客户端验证。下面记录一下注意的地方,免得以后犯同样的错误。

一、使用服务器端验证,Action Form 实现类应该扩展 ValidatorForm 而不是 ActionForm;使用客户端验证,Action Form 应该扩展 ValidatorActionForm ;
二、服务器端验证时必需的行 <html:errors /> 在客户端验证时不再需要
三、 服务器端验证时ValidatorForm 中的 需要有validate() 方法,返回return super.validate(mapping, request);,提交时调用。使用客户端验证时则不需要。
四、struts-config.xml 中action的标签中应给input属性写上来自的jsp文件名。
五、在客户端验证时,jsp文件需要注意一些事情:使用标签<html:html>;<html:form action="/submit" onsubmit="return validateSubmitForm(this);">标签中需要onsubmit属性;
六、<html:javascript formName="submitForm"/>最后需要加上这个标签,作用是Render JavaScript validation based on the validation rules loaded by the ValidatorPlugIn. 

- 作者: 太阳鱼 2004年09月21日, 星期二 11:15  回复(1) |  引用(0) 加入博采

初学struts(一)

WSAD上制作最简单的struts例子:


1.         在我们的项目中引进struts支持和JSP标签库。具体方法:在我们的WEB项目上点右键,选择“属性”——“web项目功能部件”,然后勾上“添加struts支持”和“jsp标签库”下面的所有选项

2.         建立page1.jsp文件,该文件中存在formtext输入域和提交按钮(设有usernamepasswird两项)。然后再建立page2.jsp,不需要什么内容(用于跳转到)。

注意:

u       文件中的标签使用jsp标签而不是html标签。例如:

应为<.html:form>.struts标签详见:Struts Taglibs-chm.chm

u       因为此时Action还没有建立,所以form的属性action暂时没有值,<.html:form action=“”>,建完Action后再添上。

u       form的其它属性尤其是name属性现在还不是特别清楚,需要查一下手册

3.         建立ActionForm类,例如:Form1.java。在建立的过程中需要把添加到此ActionForm中的字段选择出来,可以来自一个jsp文件,也可以同时来自多个jsp文件。可以看出我们建立的Form1.java继承了ActionForm类,只是增加了与我们所选的字段对应的成员变量,和对每个成员变量的读取、赋值、复原方法。我们可以根据需要增加方法。

注意:

新建的ActionForm信息写入了struts配置文件(struts-config.xml)中。值得注意的是如果我们不想要这个Form1.java,我们删掉后,配置文件中关于这个Form的信息依然存在,这就需要我们手动的把它删除,否则如果我们在建一个同名Form1.javaActionForm时就会出现重复,并不报错,但是到后面建立Action时会出问题。

问题:

从建立的Form1.java中和配置文件中都没有看到Form1.java对应的jsp文件的信息。是不是ActionForm直接对应的就是字段而不是——jsp——字段。如果这样的话,那对应的字段中即使来自不同文件也不能使重名的

4.         建立Action。在建立的过程中,需要选择表单bean名称和添加跳转目标page2.jsp。实际上许多逻辑和调转多转移到Action部分集中来做。

问题:

u       是否可以多个Action对应一个ActionForm,如果能拿实现一个什么样的功能?

u       是否可以多个jsp文件对应一个ActionForm,如果能拿实现一个什么样的功能?

- 作者: 太阳鱼 2004年09月16日, 星期四 08:13  回复(0) |  引用(0) 加入博采

初学java笔记(一)

一、Public,protected,private

public包内包外都可见,protected包内可见,private只有自己可见。如果不标明是那种类型,默认为protected包内可见。


二、java是强类型语言


三、java垃圾回收,不像c需要人为的释放空间,在java里当对象不再被引用时
它会认为,该对象已经没有用了,自动的隐式的释放。finalize()在释放对象之前被调用


- 作者: 太阳鱼 2004年09月7日, 星期二 08:35  回复(0) |  引用(0) 加入博采

JSP标签(一)

开发JSP页面的一个目标是和最佳做法是尽量减少java代码(表示或逻辑),这样能建立整洁的JSP页面,更容易阅读、理解和维护。实际上实现的是业务逻辑层与表示层的分离。
下面介绍编写标签的过程:


一、编写标志处理器——标志实现的java类

 1. 标志处理器要继承TagSupport类。TagSupport类实现了Tag 和 IterationTag两个接口。

 2. doStartTag():  在标记开始处由容器调用,返回值将决定是否对body content计值。返回值有两个EVAL_BODY_INCLUDE和SKIP_BODY。如果返回SKIP_BODY则不处理标签体内容,如果是EVAL_BODY_INCLUDE则在doStart()之后计算标签的体内容。

 3. doAfterBody(): 当doStartTag()方法调用完毕并且返回Tag.EVAL_BODY_INCLUDE时,将对该标记的body content进行计值处理。计值完以后,将由容器调用该方法。因为只有对body content计值,才可能触发"after body"这一事件。它也有两个返回值SKIP_BODY——不再重新求值体内容,EVAL_BODY_AGAIN——再次求值体内容;(从而可以实现对求知体内容的循环)

4. doEndTag(): 当doStartTag()方法调用完毕并且返回Tag.SKIP_BODY时或者doAfterBody()方法调用完毕并且返回IterationTag.SKIP_BODY时调用,一般在该方法中输出结果,即将结果写入JspWriter输出流中输出;该方法可以返回Tag.SKIP_PAGE或者Tag.EVAL_PAGE。前者不再对该标记以后的页面计值,后者继续对该标记以后的页面计值;

二、编写标志库描述文件(扩展名为tld的XML文件)
三、使用标签

- 作者: 太阳鱼 2004年09月2日, 星期四 10:18  回复(2) |  引用(0) 加入博采