用Java Servlets代替CGI

从网络的早期阶段开始,人们就希望他们的网络服务器不仅能够显示静态文档,通用网关接口(CGI) 扩展了服务器的能力,但其代价是增加了额外的处理进程。FastCGI则把外部CGI 处理进程同网络服务器更紧密地集成在一起,另外,对于专有的,诸如NSAPI 和ISAPI 这样的服务器API,它们直接把外部进程以服务器插件的形式集成到服务器中。现在有了Java servlets,它们的功能强大,可以快速替代你现有的CGI程序。

什么是servlets?

就象applet扩充了网络浏览器的能力一样,servlets这个Java部件,扩充了网络服务器的能力。对于任何种类的服务器端的处理,Servlets可以作为server-side includes使用或者作为CGI程序(在JavaSoft的Java Web server中可以作为插件)执行。 Servlets可以移植,不象CGI和专有的API模块,你可以利用Java的“编写一次,到处运行”的机制,在你的企业中配置网络应用程序。Servlets的运行也很稳固,在 servlet 中你创建了一个数据库连接,下一次你访问servlet时连接仍然存在,这同CGI 程序不一样。Servlets也具有扩展性,所以你可以使用面向对象的程序设计方法,来减少开发时间。Servlets可以运行在任何支持servlet的网络服务器上。目前,servlet SDK除了支持JavaSoft的Java Web server,还支持Netscape, Apache 和IIS,以及大量第三方的网络服务器。

JSDK导游

为了创建servlets,你需要Java servlet SDK (JSDK),它可以从JavaSoft网站下载。JSDK包含诸如javax.servlet,javax.servlet.http等包,其中包含有你自己创建servlets时所需要的类和接口。对于sun.servlet 包来说,其中包含了网络服务器用来运行servlets所需要的类。 (对Servlet的支持通常是通过服务器插件的形式)。一旦你有了JSDK,你只要创建GenericServlet类的子类,并且重载若干方法。GenericServlet 定义了你应该重载的三种主要方法: init(), service()和destroy()。

init() :初始化你的servlet,诸如打开数据库连接。

destroy():在applet运行结束后,清除servlet 自身。

service():每次调用servlet时,就调用service()方法。有两个对象 ServletRequest和ServletResponse需要传送给servlet,用于处理客户请求。

为了帮助处理基于Web 的事务,JSDK 在 javax.servlet.http包中有个HttpServlet类。HttpServlet是从GenericServlet中派生出来的,它提供了service()的一个实现,该实现用于自动处理GET, HEAD和POST的请求。

HttpServlet类中的方法有doGet()和doPost()。一个典型的CGI servlet只需要实现doGet()和doPost()方法。 doGet()和doPost()的参数为HttpServletRequest和HttpServletResponse。

HttpServletRequest是个接口,该接口提供了从客户的请求获取信息的一些方法。例如, getParameter()方法返回在客户请求中的关键字/值对(或者从请求串中取得,或者从POSTed数据中取得)。

HttpServletResponse提供了输出流,使得servlet把HTML格式的输出返回给客户。

基本Servlet代码

代替你的CGI

下面为一段可以取代CGI程序的基本的servlet代码。Servlet完成如下的简单事情:列出由HTML表单搜集的关键字/值对(key/value)。

BasicCGIServlet处理POST,也用同样处理GET。所以doPost()和doGet()都调用doService()。doService()可以在子类中重载,以实现更多特定的功能。

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

public class BasicCGIServlet extends HttpServlet {

public BasicCGIServlet () {

super();

}

public void doPost (HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

doService(req, resp);

}

public void doGet (HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

doService(req, resp);

}

protected synchronized void doService (HttpServletRequest req,

HttpServletResponse resp) throws ServletException, IOException {

// get an output stream to write to

ServletOutputStream out = resp.getOutputStream();

// set the content type for the response

resp.setContentType (\\"text/html\\");

// optionally you should also set any special content-encoding

// and content length response headers, and return status codes

// write out the response!

out.println (\\"<body

bgcolor=\\\\"white\\\\">\\");

out.println (\\" \\");

out.println (\\"

\\");

for (Enumeration e = req.getParameterNames(); e.hasMoreElements(); ) {

String key = (String) e.nextElement();

out.println (\\"

\\");

}

out.println (\\"

Key Value
\\" + key + \\" \\" + req.getParameter(key) +

\\"

\\");

}

}

当调用req.getParameterNames()时,servlet请求对象读入表单数据,并且把它解码为关键字/值对(事实上,一旦第一次调用getParameterNames(),或者getParameterValues(),或者getParameter()

时,就进行解码)。 getParameterNames()返回所有关键字的列举。getParameter()返回同特定关键字相对应的值。当servlet请求被解析成关键字/值对时,每个关键字的值保存在String数组中,以便可以处理一个关键字有多个值的情况。调用getParameterValues(),返回的是String数组,而调用 getParameter()后,则仅返回String数组中的第一个元素。

你也许会注意到doService()是个同步化的方法。这是因为servlets 通常是在多线程环境下运行的。因为网络服务器创建的servlet对象只有一个实例,所以servlet必须能够对同时发生的请求提供服务。因此,Servlets需要确保:这些请求在访问共享资源时保持同步。这些共享资源包括实例变量,数据库连接和文件流等。

运行你的servlet

一旦编写好servlet,并且编译成功之后,你可以把它放到网络服务器中servlet别名目录中。就同服务器中的cgi-bin别名目录的作用一样,任何放在servlet 目录中的文件,一旦被作为url的一部分被请求时,将被作为servlets执行。例如,BasicCGIServlet可以通过如下的url调用: http://mycompany.com/servlet/BasicCGIServlet。你既可以直接调用该url (并且传送给servlet一个请求关键字/值对的串),也可以通过HTML表单中的一个动作来调用。要了解更多的支持servlet的网络服务器的信息,请参阅JSDK中的有关文档信息。

进一步的用法

GenericServlet和 HttpServlet提供了一个构建servlets的固定的基类。通过重载service()方法,你可以在它们的基础上进行构建。例如,你可以加入对响应缓存的支持(请参见HttpServlet 中的getLastModified()),也可以加入对HTTP 1.1方法的支持,等等。你甚至可以构建一个扩展的模板引擎。(有谁真的喜欢在他们的程序中内置HTML代码呢?)

另外一个用法是对JSDK进行扩展,使之除了支持标准的application/x-www-form-urlencoded mime 类型之外,还支持其他类型的表单编码。例如,你可以加入对multipart/form-data mime类型的支持,用于处理通过HTTP上载文件。接口方法getParameterNames(), getParameterValues()等等,都是在sun.servlet包中实现的,所以你需要配置JSDK ,以便加入这些支持。还有一种变通的方法,你可以自己实现有关方法,但那样做,就需要复制代码或者改变JSDK的语义。上面的这些方法都是可行的,但是没有哪一种是完美无缺的。

结论

现在你应该会自己创建Java servlets了,它们可以用来代替传统的Perl和C/C++ CGI程序。 Java的面向对象的特性和“编写一次,到处运行”的机制使得Java servlets的编写很简单。Servlet的稳固性,可以解决有关状态管理问题,而这些都是只用一次的CGI程序解决实际问题时通常会遇到的难题。 Servlets可以利用Java语言的所有功能,包括JDBC和RMI。由于大多数网络服务器都加入了对servlet的支持,Java将迅速成为开发企业级应用程序的一种可选语言。

时间: 2024-11-16 20:41:26

用Java Servlets代替CGI的相关文章

HTML5 Server-Sent Events With Java Servlets Exampl

Since the dawn of modern web applications, push notifications have gained significant traction in industry. Instead of pooling data from server it has now become common that server should notify client. Ajax is so pervasive these days it is almost se

Jmeter零起点学习

什么是JMeter Apache JMeter是一个开源的Java桌面软件.设计的目的就是进行C/S架构软件的负载测试.随着发展,有很多人也用来进行一些静态资源或者动态资源的性能测试.可以支持的测试对象有:静态文件,Java Servlets, CGI scripts,Java 对象,数据库,FTP服务器等等. JMeter的原理就是模拟产生一个大数据压力包,然后使用不同的负载测试方法去研究server,object或者network的健壮性以及分析在过载情况下的性能指标. 当然,对于一些简单的

Java Servlet与Applet、CGI、JSP的比较

Java Servlet是一种独立于平台和协议的服务器端的Java应用程序,可以生成动态的Web页面. Java Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机. Java Servlet与Applet 的比较: 相似之处: ◆它们不是独立的应用程序,没有main()方法. ◆它们不是由用户或程序员调用,而是由另外一个应用程序(容器)调用

JAVA多线程和并发基础面试问答(转载)

原文链接:http://www.cnblogs.com/dolphin0520/p/3932934.html 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题. Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含

JAVA多线程和并发基础面试问答

原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题.(校对注:非常赞同这个观点) Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环

JAVA多线程和并发基础面试问答【转】

JAVA多线程和并发基础面试问答 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题.(校对注:非常赞同这个观点) Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和程序的单 一进程.线程可以被称为轻量

Java开发工具

每一个程序员都有一个自己的开发工具,使用得心应手,好的工具能做到事半功倍效果.但人与人不同,喜好不同,使用的工具也不同.就像侠客需要武器,十八般兵器,各有所长,每个侠客都有属于自己的兵器.下面介绍下IT界的兵器们: JDK (Java Development Kit)Java开发工具集 .Eclipse.MyEclipse.UltraEdit.Java Workshop.NetBeans 与Sun Java Studio 5.Borland 的JBuilder.Oracle 的JDevelope

17、JAVA多线程和并发基础面试问答

JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题.(校对注:非常赞同这个观点) Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(se

Java Servlet API中文说明文档

Java Servlet API中文说明文档译者前言:       近来在整理有关Servlet资料时发现,在网上竟然找不到一份中文的Java Servlet API的说明文档,而在有一本有关JSP的书后面附的Java Servlet API说明竟然不全,而这份文档的2.1a版在1998年的11月份就已定稿.所以我决定翻译一份中文的文档(其中一些与技术关系不大的部分已被略去),有兴趣的读者可以从http: //java.sun.com/products/servlet/2.1/servletsp