全部博文(83)
分类: Java
2005-07-24 11:29:15
Servlets是JAVA 2.0中新增的一个全新功能, Servlets是一种采用JAVA技术来实现CGI功能的一种技术。Servlet和CGI一样都是运行在WEB服务器上,用来生成WEB页面。
一、JAVA Servlets为什么优于传统的CGI
JAVA Servlets比传统的CGI或其它CGI类似替代技术来说,效率更高,使用更方便,功能更强大,更小巧也更便宜:
1)效率,传统CGI对每一个HTTP请求都要产生一个新的进程。如果某个CGI程序是一个执行非常快的操作,打开进程的时间也许占用了大部分执行时间。而对JAVA Servlets来说,在JAVA 虚拟机上,每一个请求由一个'小'JAVA线程(thread)响应,而不是一个`大`操作系统进程。类似地,传统CGI如果对同一个CGI程序有N个同时请求,这个CGI程序的代码将被导入内存N次。JAVA Servlets 产生N个线程,但只有一个JAVA Servlets CLASS的copy。同时JAVA Servlets比CGI有更多的优化选择,象预先计算,打开数据库连接等。
2)方便,JAVA Servlets能自动的粘贴和解码HTML表单数据,读和设置HTTP头,处理COOKIES,跟踪SESSIONS,等其它大量功能。
3)强大的功能,JAVA Servlets可以很容易的实现对CGI来说是不可能或很困难的事务。JAVA Servlets能直接和服务器进行通讯而CGI是不能的。
4)JAVA Servlets之间能共享数据,很容易实现诸如数据库连接池。它能方便的实现管理从REQUEST到REQUEST请求,简化SESSION和获取前一页面。而CGI之间通讯差,由于每个CGI程序的调用都开始一个新的进程,调用间通讯通常要通过文件进行,因而相当缓慢。同一台服务器上的不同CGI程序之间的通讯也相当麻烦。
5)调用时间:CGI程序是作为单独过程运行的,通常调用时间较长,这个间接成本在每次调用的时候都要发生。在使用解释器的时候调用时间会更长。而内存中的servlet可以非常迅速地加载。
6)安全:有些CGI版本有明显的安全弱点。即使是使用最新的标准和PERL等语言,系统也没有基本安全框架,而要靠一组事实上的规则。而java定义有完整的安全机制,包括ssl,ca认证,安全政策等规范。
7)小巧,JAVA Servlets使用JAVA编写,遵循标准API。它能直接或借助插件在几乎所有WEB服务器上运行。
8)价格低,显然,有很多都是FREE。
Servlet的一些应用范围:
1) 用于处理HTML表单:通过HTTP产生POSTed数据,包括买卖订单或信用卡数据。因此servlet可以成为订单处理系统的一部分,和产品存货数据库一道工作,也许可以用在在线支付系统上。
2)允许人们之间的合作:一个servlet能并发处理多个请求;他们可以使用在诸如在线会议这样的同步请求支持系统。
3) 转送请求:Servlet可以转送请求给其他的服务器和servlets。这就允许在镜象同样内容的几个服务器之间平衡负载。按照任务类型或组织范围,可以允许被用来在几个服务器中划分逻辑上的服务器。
4) servlet 编写者们可以定义彼此之间共同工作的激活代理,每个代理者是一个servlet,而且代理者能够在他们之间传送数据。
二、Servlet的结构
在具体掌握servlet之前,须对java语言有所了解。下面是基于您了解java基础上的,在Servlet API中最重要的是Servlet interface. 所有的servlets implement(执行)这个interface, 方式多种:或者是直接的,或者通过扩展类(class)执行它,如 HttpServlet。 这个Servlet interface 提供安排servlet与客户端联系的方法. Servlet 编写者可以在他们开发 servlet程序时提供更多一些或所有的这样方法.
当一个servlet接收来自客户端的调用请求, 它接收两个对象: 一个是ServletRequest,另外一个是ServletResponse. 这个ServletRequest类概括从客户端到服务器之间的联系, 而 ServletResponse类概括从servlet返回客户端的联系.
ServletRequest interface 可以获取到这样一些信息如由客户端传送的阐述名称,客户端正在使用的协议, 产生请求并且接收请求的服务器远端主机名. 它也提供获取数据流的servlet, ServletInputStream, 这些数据是客户端引用中使用HTTP POST 和 PUT 方法递交的. 一个ServletRequest的子类可以让 servlet获取更多的协议特性数据. 例如: HttpServletRequest 包含获取 HTTP-specific头部信息的方法.
ServletResponse interface 给出相应客户端的servlet方法. 它允许servlet 设置内容长度和回应的mime类型, 并且提供输出流, ServletOutputStream, 通过编写者可以发回相应数据. ServletResponse子类可以给出更多 protocol-specific容量的信息。 例如: HttpServletResponse 包含允许servlet 操作HTTP-specific头部信息的方法.
上面有关类和 interfaces描述构成了一个基本的Servlet框架. HTTP servlets有一些附加的可以提供session-tracking capabilities的方法. servlet编写者可以用这些API在有他人操作时维护servlet与客户端之间的状态.
三、Servlet的接口
Servlet 从javax包的httpservlet类扩展,在HttpServlet中加入了一些附加的方法,这些方法可以被协助处理HTTP 基本请求的HttpServlet类中的方法service自动地调用。这些方法有:
doGet 用来处理HTTP的GET请求。
这个GET操作仅仅允许客户从HTTP server上"取得"(GET)资源。重载此方法的用户自动允许支持方法HEAD。这个GET操作被认为是安全的,没有任何的负面影响,对用户来说是很可靠的。比如,大多数的正规查询都没有副作用。打算改变存储数据的请求必须用其他的HTTP方法。这要求方法也必须是个安全的操作。方法doGet的缺省执行将返回一个HTTP的BAD_REQUEST错误。
方法doGet的格式:
protected void doGet(HttpServletResquest request,
HttpServletResponse response)
throws ServletException,
IOException;
doPost 用来处理HTTP的POST请求。
这个POST操作包含了在必须通过此servlet执行的请求中的数据。由于它不能立即取得资源,故对于那些涉及到安全性的用户来说,通过POST请求操作会有一些副作用。
方法doPost的缺省执行将返回一个HTTP的BAD_REQUEST错误。当编写servlet时,为了支持POST操作必须在子类HttpServlet中实现(implement)此方法。
此方法的格式:
protected void doPost(HttpServletResquest request,
HttpServletResponse response)
throws ServletException,
IOException;
doPut用来处理HTTP的PUT请求。
此PUT操作模拟通过FTP发送一个文件。对于那些涉及到安全性的用户来说,通过PUT请求操作也会有一些副作用。
此方法的格式:
protected void doPut(HttpServletResquest request,
HttpServletResponse response)
throws ServletException,
IOException;
doDelete用来处理HTTP的DELETE请求。
此操作允许客户端请求一个从server移出的URL。对于那些涉及到安全性的用户来说,通过DELETE请求操作会有一些副作用。
方法doDelete的缺省执行将返回一个HTTP的BAD_REQUEST错误。当编写servlet时,为了支持DELETE操作,必须在子类HttpServlet中实现(implement)此方法。
此方法的格式:
protected void doDelete (HttpServletResquest request,
HttpServletResponse response)
throws ServletException,IOException;
doHead 用来处理HTTP的HEAD请求。
缺省地,它会在无条件的GET方法执行时期中运行,但是不返回任何数据到客户端。只返回包含内容信息的长度的header。由于用到GET操作,此方法应该是很安全的(没有副作用)也是可重复使用的。此方法的缺省实现(implement)自动地处理了HTTPDE的HEAD操作并且不需要通过一个子类实现(implement)。
此方法的格式:
protected void doHead (HttpServletResquest request,
HttpServletResponse response)
throws ServletException,
IOException;
doOptions用来处理HTTP的OPTIONS请求。
此操作自动地决定支持什么HTTP方法。比如说,如果一个servlet的作者创建HttpServlet的子类并重载方法doGet,然后方法doOptions会返回下面的header:
Allow:GET,HEAD,TRACE,OPTIONS
一般不需要重载方法doOptions。
此方法的格式:
protected void doOptions (HttpServletResquest request, HttpServletResponse response)
throws ServletException,
IOException;
doTrace用来处理HTTP的TRACE请求。
此方法的缺省执行产生一个包含所有在trace请求中的herder的信息的应答(response)。
在开发servlet时,多数情况下需要重载此方法。
此方法的格式:
protected void doTrace (HttpServletResquest request,
HttpServletResponse response)
throws ServletException,
IOException;
在开发以HTTP为基础的servlet中,Servlet开发者关心方法doGet和方法doPost即可。
四、Servlet的生命周期
如果你写过java的小应用程序(Apple),那Servlet对你来说就不会太难,SZ更为简单因为Servlet不用考虑图形界面的应用,而与小应用程序一样,Servlet与有一个生命周期。Servlet的生命周期是当服务器装载运行servlets:接收来自客户端的多个请求并且返回数据给客户端. 然后在删除移开servlets.下面详细描述如下:
1)初始化时期
当一个服务器装载servlet时, 它运行servlet的 init() 方法.
public void init(ServletConfig config) throws ServletException
{ super.init(); //一些初始化的操作,如数据库的连接 }
需要记住的是一定要在init()结束时调用super.init().init()方法不能反复调用,一旦调用就是重装载servlet. 直到服务器调用destroy方法卸载servlet后才能再调用.
2)Servlet的执行时期
在服务器装载初始化servlet后, servlet就能够处理客户端的请求. 用 service 方法做到这一点. 每个客户端请求有它自己service方法: 这些方法接收客户端请求, 并且发回相应的响应.Servlets能同时运行多个service. 这是很重要的, 这样, service方法可以按一个thread-safe 样式编写. 如:service方法更新servlet对象中的一个字段field, 这个字段可以同时存取的. 假如某个服务器不能同时并发运行 service方法,也可以用SingleThreadModel interface. 这个 interface 保证不会有两个以上的线程threads并发运行. 在Servlet执行期间其最多的应用是处理客户端的请求并产生一个网页。其代码如下:
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println("");
out.println("Hello World");
out.println("");
out.close();
3)Servlet结束时期
Servlets一直运行到他们被服务器卸载。在结束的时需地收回在init()方法中使用的资源,在Servlet中是通过destory()方法来实现的。
public void destroy()
{
//回收在init()中启用的资源,如关闭数据库的连接等。
}
五、Servlet应用实例
现在我们来一个简单的例子来说明Servlet的应用,其完全成的功能是读取表单的内容并输出到浏览器上。
test.html test.java
姓名:
Email:
意见:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class test extends HttpServlet {
private DBConnectionManager connMgr;
//Initialize global variables
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
//Process the HTTP Get request
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
String name=request.getParameter("name");
String mail=request.getParameter("mail");
ServletOutputStream out=response.getOutputStream ();
out.println("");
out.println("");
out.println("");
out.println(name);
out.println("
");
out.println(mail);
out.println("");
out.close();
}
//Process the HTTP Post request
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
public void destroy() {
}
}
把test.html放入web服务器的根目录下,而test.java 这个servlet编译成class后一般都放在web服务器的class目录下,在resin中是放在docWEB-INFclasses目录下,而resin能在运行时自动编译,报所以直接报test.java 放在docWEB-INFclasses目录下即可。
原作者:javaduke
来 源: