服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用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 (//"form parameters bgcolor=////"white////">//");

out.println (//"

//");

out.println (//"

//");

for (enumeration e = req.getparameternames(); e.hasmoreelements(); ) {

string key = (string) e.nextelement();

out.println (//"

//");

}

out.println (//"

keyvalue
//" + 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将迅速成为开发企业级应用程序的一种可选语言。

扫描关注微信公众号