23 二月 2008

实现Tag接口的标签处理器的生命周期

Tag

1、容器在创建标签处理器的实例后,调用setPageContext()方法设置标签的页面上下文,然后调用setParent()方法设置这个标签的父标签,如果没有父标签,则设置为null。

2、调用标签处理器的setXXX()方法,设置标签的属性。如果没有定义属性,则没有这个步骤。

3、调用doStartTag()方法,该方法可以返回EVAL_BODY_INCLUDE或者SKIP_BODY。如果返回EVAL_BODY_INCLUDE,则将标签体输出到当前的输出流中;如果返回SKIP_BODY ,则忽略标签体。

4、调用doEndTag()方法,该方法可以返回EVAL_PAGE或者SKIP_PAGE。如果返回前者,则执行JSP页面的余下部分;如果返回后者,则忽略JSP页面的余下部分。

5、容器会缓存标签处理器的实例,一旦遇到同样的标签,则重复使用缓存的标签处理器实例。

6、当需要释放标签处理器实例时,release()方法才被调用。

实现IterationTag接口的标签处理器的生命周期

IterationTag

1、容器在创建标签处理器的实例后,调用setPageContext()方法设置标签的页面上下文,然后调用setParent()方法设置该标签的父标签,如果没有父标签,则设置为null。

2、调用标签处理器的setXXX()方法,设置标签的属性。如果没有定义属性,则没有该步骤。

3、调用doStartTag()方法,该方法可以返回EVAL_BODY_INCLUDE或者SKIP_BODY。如果返回EVAL_BODY_INCLUDE,则执行标签体;如果返回SKIP_BODY,则忽略标签体。

4、执行完标签体之后,doAfterBody()方法被调用,该方法可以返回EVAL_BODY_AGAIN或者SKIP_BODY。如果返回EVAL_BODY_AGAIN ,则重复执行标签体。如果返回 SKIP_BODY,则不再执行标签体。注意,在调用该方法之前,标签体已经被执行了一遍,如果要忽略标签体,需要在doStartTag()方法中返回SKIP_BODY

5、调用doEndTag()方法,该方法返回EVAL_PAGE 或者 SKIP_PAGE。如果返回EVAL_PAGE,则执行JSP页面的余下部分;如果返回SKIP_PAGE,则忽略JSP页面的剩余部分。

6、 容器会缓存标签处理器实例,一旦遇到同样的标签,则重复使用缓存的标签处理器实例。

7、当需要释放标签处理器实例时,release()方法才被调用。

实现Tag接口的标签处理器的生命周期

Tag

1、容器在创建标签处理器的实例后,调用setPageContext()方法设置标签的页面上下文,然后调用setParent()方法设置这个标签的父标签,如果没有父标签,则设置为null。

2、调用标签处理器的setXXX()方法,设置标签的属性。如果没有定义属性,则没有这个步骤。

3、调用doStartTag()方法,该方法可以返回EVAL_BODY_INCLUDE或者SKIP_BODY。如果返回EVAL_BODY_INCLUDE,则将标签体输出到当前的输出流中;如果返回SKIP_BODY ,则忽略标签体。

4、调用doEndTag()方法,该方法可以返回EVAL_PAGE或者SKIP_PAGE。如果返回前者,则执行JSP页面的余下部分;如果返回后者,则忽略JSP页面的余下部分。

5、容器会缓存标签处理器的实例,一旦遇到同样的标签,则重复使用缓存的标签处理器实例。

6、当需要释放标签处理器实例时,release()方法才被调用。

09 二月 2008

动作元素include和include指令的区别

初学JSP,我们可能对<jsp:include>元素和include指令有所混淆,认为两者是一样的。虽然从表象上来看,两者的效果差不多,但是实质上是有区别的。





  1. include指令所包含的对象是静态对象,<jsp:include>动作包含的对象是动态对象。所谓的静态对象和动态对象并不是指静态html页面和动态页面。所谓的静态和动态指的是:include指令将JSP页面作为静态对象,将页面的内容(可以是文本或者代码)在include指令的位置处包含进来,这个过程发生在JSP容器管理JSP页面生命周期的转换阶段。而<jsp:include>动作包含的JSP页面作为动态对象,在请求处理期间,将请求发送给改对象,然后将最后处理的结果重新包含在当前页面的请求响应中,这个过程发生在JSP页面生命周期的执行阶段。




  2. include指令的file属性所给出的路径是相对于当前文件的,而<jsp:include>动作的page属性所指的路径是相对于当前页面的。




当使用include指令包含某个资源时,资源路径的查找是在JSP页面的转换期间发生的,一旦找到该资源(文本、代码或者JSP页面),它的内容就会在include指令的位置处被包含进来,成为一个整体,然后转换为Servlet源文件。而采用<jsp:include>动作包含资源时,相对路径的查找是在处理阶段完成的,当前页面和被包含的资源是相互独立的个体,当前页面将请求发送给被包含的资源,被包含的资源对请求处理的结果作为当前页面对请求响应的一部分发送给客户端。





  1. 两者发生的时间不同。include指令发生在转换阶段,后者发生在处理阶段。



Tomcat数据库连接池简单配置

一般情况下,我们要建立数据库连接,首先需要调用Class.forName()加载数据库驱动,然后调用驱动管理器建立数据库连接对象(即Connection对象)。


但是这种方式的数据库连接存在一个很大的问题。当访问量增多时,每一次不同用户的连接都需要经过一系列繁琐的步骤,最后访问结束,还需要关闭结果集,语句对象,连接对象。比较麻烦,而且这样的访问浪费很多时间。


在大型Web应用中,Servlet容器可能同时会接收到多个客户端的上千个请求,如何快速的对每个请求进行响应和服务十分重要。如果采用一个请求一个请求的处理,会导致响应时间非常迟钝。一种较好的解决方案就是采用多线程并发处理每个请求。


Servlet容器维护了一个线程池来服务请求。线程池实际上是等待执行代码的一组线程,这些线程我们称之为工作者线程。当Servlet容器接收到一个访问请求时,Servlet容器从线程池中选取一个工作者线程,将请求传递给该线程,然后由这个线程执行Servletservice()方法。如果当这个线程正在执行,而此时容器又接收到另一个请求,那么容器将会在线程池中选择另一个线程来对新的请求进行服务。这就是数据库连接池的最基本的作用。


显然,通过数据库连接池,能够很大程度上提高web容器的效率。


下面,我们就简单实现一个tomcat连接池的应用。


环境:jdk6.0tomcat5.5MySQL5.0 myeclipse6.0 Windows XP Pro


第一步:基本工作。


建立数据库test,建立表stu,两个字段,一个是学号(整型),一个是姓名(字符串),在myeclipse建立一个web工程test(为了省事,所以都起名为test),使用tomcat5.5作为web容器。



第二步:编写数据库访问代码(读取表stu中的记录)

代码

javax.sql包中,定义了DataSource接口,给我们提供了通过连接池建立数据库连接的方式。DataSource接口由驱动程序供应商来实现。利用DataSource建立数据库连接,不需要在客户程序中加载JDBC驱动。在程序中,通过向一个JNDIJava Naming and Directory)服务器查询来得到DataSource对象,然后调用DataSource对象的getConnection()方法来建立数据库的连接。以上代码就是描述的这个过程。


当访问完数据库之后,就可以调用close()方法结束数据连接。在普通的数据库访问程序中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用线程池技术,客户程序得到的连接对象是连接池中物理连接的一个句柄,调用连接对象的close()方法之后,物理连接并没有关闭,只是删除了客户程序中连接对象和连接池中连接对象之间的联系。


第三步:在Tomcat中配置JDBC数据源。


JDBC数据源配置放到当前Web应用程序运行目录的配置文件中,如果当前你的工程名为“test”,你可以将你的Web应用程序配置文件起名为“test.xml”,编辑%CATALINA%/conf/Catalina/localhost/test.xml。内容如下:


 


部署描述符配置

在配置文件中Resource元素中,指定的JNDI名称为test。这个名称不一定非要和Context元素的名字一样,可以任起。


第四步:工程部署,运行。


结果如下:


运行结果

我们成功的以数据源的方式读取了数据库中的数据。

Session和Cookie的学习

Session属于服务器端技术,在服务器端创建,其实质通过散列表来存储信息。例如HashMap对象存储属性名和属性值。


CookieNetscape公司发明的,它也用来跟踪用户会话。但是Cookies是由服务器端发送给客户端的信息片段,存储在客户端浏览器的内存或者客户端硬盘上,在客户请求中发回。


SessionCookie的最大区别在于:前者在服务器端保存,而后者在客户端保存。


为了跟踪用户会话,服务器端在创建Session后,需要将Session ID交给客户端,在客户端下次请求时,将这个ID随请求一起发送回来。可以采用Cookie(这种保存Session IDCookie我们称之为会话Cookie)URL重写的方式,将Session ID发送给客户端。


Servlet规范中,会话跟踪的Cookie的名字必须是JSESSIONID,它通常保存在浏览器的内存中。浏览器内存中的会话Cookie在关闭浏览器的时候会自动删除,不能在多个浏览器进程之间共享。而如果我们自己创建一个Cookie实例,则可以保存Cookie信息,在浏览器关闭后,再次打开,仍然存在,而且可以在多个浏览器进程间共享。


但是要注意,虽然每次打开一个新的浏览器进程,会发现开始一个新的会话,但是并不是意味着上次的Session消失了。主要是因为会话Cookie保存在浏览器内存中,当浏览器关闭时,会话Cookie被删除了,从而导致下一次浏览器请求中,没有相应的Session ID,从而导致服务器创建新的会话。

JDBC介绍

JDBC介绍


数据库现在作为各种应用和系统的主要数据源之一,它的作用已经越来越重要。为了访问数据库中的数据,在Windows平台下,提供了统一的数据库访问方式,微软推出了ODBC(开放式数据库连接),并提供了ODBC API,使用者在程序中只要调用ODBC API ,由ODBC驱动程序将调用请求转换为对特定数据库的调用请求。为了在Java语言中提供对数据库访问的支持,Sun公司于96年推出了JDBCJava数据库连接)。


JDBC描述了一组访问关系数据库的标准Java类库。我们通过使用这些类库,连接到关系数据库,通过SQL语句,对数据进行处理。JDBC不但提供了访问关系数据库的标准API,还为数据库厂商提供了一套标准的规范,数据库厂商只要遵循这套规范,就可以很灵活的为自己的数据库产品提供JDBC驱动支持,这些驱动程序可以是Java程序访问数据库的效率大大提高。


JDBC的驱动程序可以分为四类,分别是:





  • JDBC-ODBC




  • 部分本地API,部分Java驱动程序




  • JDBC网络纯Java驱动程序




  • 本地协议Java纯驱动程序




 





  1. JDBCODBC





因为微软推出的ODBCJDBC时间要早,因此绝大部分数据库都可以通过ODBC来访问,因此Sun公司推出JDBC的时候,为了支持更多的数据库,提供了JDBC-ODBC桥。JDBC-ODBC本身就是一个驱动,只不过,我们利用这个驱动,表面上使用的JDBCAPI,而实质上是通过内部调用ODBC区访问数据库。这种桥机制实际上是把JDBC调用转换成ODBC调用,并通过ODBC库把它们发送给ODBC数据源。


通过桥式连接访问数据库,需要经过多层调用,因此利用桥式连接访问数据库的效率比较低。当数据库么有提供JDBC驱动,只有ODBC驱动的情况下,此时才考虑桥式连接。


这种访问要求客户的机器上安装JDBC-ODBC桥驱动、ODBC驱动程序和相应数据库 的本地API。在JDK中,已经提供了JDBC-ODBC桥的实现类。





  1. 部分本地API Java驱动程序


    大部分数据库厂商都提供了与他们的数据库产品进行通信所需要的API,这些API往往用C语言或类似的语言编写,依赖于具体的平台。这一类型的JDBC驱动程序使用Java编写,它调用数据库厂商提供的本地API。当我们在程序中利用JDBC API访问数据库时,JDBC驱动程序将调用请求转换为厂商提供的本地API调用,数据库处理完请求将结果通过这些API返回,进而返回给JDBC驱动程序,JDBC驱动程序将结果转化为JDBC标准形式,再返回给客户程序。





通过这种类型的JDBC驱动程序访问数据库减少了ODBC的调用环节,提高了数据库访问的效率,并且能够充分利用厂商提供的本地API的功能。


这种访问,要求客户的机器上安装本地JDBC驱动程序和特定厂商的本地API





  1. JDBC网络纯Java驱动程序





这种驱动利用作为中间件的应用服务器来访问数据库。应用服务器作为一个到多个数据库的网关,客户端通过它可以连接到不同的数据库服务器。应用服务器通常都有自己的网络协议,Java客户程序通过JDBC驱动程序将JDBC调用发送给应用服务器,应用服务器使用本地驱动程序访问数据库,从而完成请求。





  1. 本地协议的纯Java驱动程序




这种类型的JDBC驱动程序完全用Java编写,通过与数据库建立直接的套接字连接,采用具体于厂商的网络协议把JDBC API调用转换为直接的网络调用。
这种类型的驱动是四种类型驱动中访问数据库效率最高的。不过,因为每个数据库厂商都有自己的协议,因此,访问不同厂商的数据库,需要不同的JDBC驱动。目前,主流的数据库厂商(OracleMicrosoftSybaseMySQL等)都为他们各自的数据库产品提供了这种类型的驱动。

04 二月 2008

超搞笑!从朋友那边转的。

来过兰州的和在兰州生活的人都应该知道兰州的106公交车是多么的生猛和膘悍,我是一个现在是一个兰州公交集团的员工没天看到他们从我边上飞过去的时候才真正知道这个对手的可怕。不知道大家听说过关于106的这两个神话没有。一个是有一次106 司机飚车的时候车轮起火了;另一个是106刹车的时候一个乘客把那根直的铁扶手拉弯了……
每每跟朋友说起,朋友就会跟我说他们坐在106上看着106一辆一辆的超过Taxi时的壮观,想着1元换来如此超值的服务是多么的爽。有一次我有一个兰州的朋友说:"106超taxi那算不了什么壮观,壮观的是106超106!" 后来有人评论说要想不迟到请坐106!
有位朋友刚来兰州的时候,第一次和我出去玩,坐的就是106,结果一开车他就从座位上摔下来了!
当1辆106路从你身旁呼啸而过时,据说会出现时空扭曲的现象……
4 辆106 在白银路举行飚车赛的话,足以在上空打开一个时空门了。再多一辆当时肯定造成了重力失常,磁场混乱,火车出轨,轮船触礁,飞机失事,地震,山崩,海啸,酸雨,泥石流,龙卷风,太阳黑子爆发,小行星撞击地球……甚至把外星人招来。后果不堪设想。
车轮起火偶倒是碰见过,而且是在后车轮那次真的好怕怕啊!太agree了,106超106,那就是NEED FOR SPEED极品飞车的感觉。就像警匪片里拍的那样……感觉和坐喷气式飞机一样……绝对正确。
曾经坐过一趟106,连着超过了两辆106……还有一次竟然有个人胆敢在两辆106之间想穿过马路,其胆量着实惊人!
我们曾经讨论过请106司机组成一个F1方程式车队的可能性,最后的结论就是,进入三甲应该没问题的。我觉得舒马赫退役之后,来兰州开106是一个不错的选择。不过,他肯定不能象他在f1 赛场上那样风光无限了。兰州公交车司机里高手如云。
  那以前听别人在外面吹牛。
问:你做什么的?
答:我******在兰州开106路公交。
旁人一阵羡慕的眼光…… 我现在说开103 大家眼光也是那么的有神!因为他知道我每天在西津路的对手是谁!
有次坐106,遇到一个强人,坐在最后一排最中间,面朝车内的走道没有扶手可扶……一刹车,他顺着走道滚到引擎盖那边。还好那人身体素质好,应该小时候练过什么工夫。
兰州公交是喜欢兰州的理由!逛街坐106,回来发现朋友同事都已经毕业,结婚生子了。时钟变慢,尺子变短。(据说速度快到一定极限就能穿越时空)普林斯顿正在考虑和106车队共建世界级实验室,以期待证明大统一场理论,同时在乘客中普及爱因斯坦的相对论。
据说普利斯通公司和米其林公司为了争夺106路07的赞助权正打的不可开交。
过两天再坐坐106去,好久没体验,,光是看着106跑,那激情都很澎湃了.何况和他们同场竞技 真是享受!

另:据说最近杀出一路更快的111路,从兰海商贸城到西关,在甘南路就可以搭,那才叫…
…有一次撞到树了,树把车身劈成两半,两米多啊
三客司 一车队 王健 QQ65574607 欢迎拍砖