Servlet和CGI的区别
考点:考察求职者对Servlet技术的理解。
出现频率:★★★★
【面试题解析】
Servlet是用Java编写的Server端程序,它运行在基于Java语言的Web服务器端,与协议和平台无关。Java Servlet可以动态地扩展服务器的能力,并采用请求/响应模式提供Web服务。
Servlet有如下特点。
• 高效。在传统的CGI中,每个请求都要启动一个新的进程,如果CGI程序本身的执行时间较短,启动进程所需要的开销很可能反而超过实际执行时间;在Servlet中,每个请求由一个轻量级的Java线程处理,而不是重量级的操作系统进程。在传统CGI中,如果有N个并发的对同一CGI程序的请求,则该CGI程序的代码在内存中重复装载了N次;对于Servlet,处理请求的是N个线程,只需要一份Servlet类代码。在性能优化方面,Servlet也比CGI有着更多的优势,例如缓冲以前的计算结果、保持数据库连接等。
• 方便。Servlet提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等。
• 功能强大。Servle可以轻松地完成许多使用传统CGI程序很难完成的任务。例如,Servlet能够直接和Web服务器交互,而普通的CGI程序不能。Servlet还能够在各个程序之间共享数据,使得数据库连接池之类的功能很容易实现。
• 可移植性好。Servlet用Java编写,Servlet API具有完善的标准。几乎所有的主流服务器都直接或通过插件支持Servlet。
• 节省投资。基于Java语言的Web服务器非常普遍,无论是小规模网站还是企业级应用的开发成本和维护成本都相对低廉。
CGI程序,主要用Perl、Shell Script或C编写,能够向客户端提供动态内容。
下面的CGI和Servlet程序的功能均为获得客户端在浏览器表单中输入的参数(Firstname和Lastname),并将返回给客户端。相应的CGI程序和Servlet程序分别如下所示。
• CGI程序(Perl)
$query?string=$ENV{?QUERY?STRING?}; $query?string=As/%([dA-Fa-f][dA-Fa-f])/pack(″C″,hex()$1))/eg;$query?string=As/+ //g; @pairs=split(/&/,$query?string); foreach $pair(@pairs) { ($key,$value)=split(/=/,$pair); $form?data{$key}=$value; } $firstname=$form?data{″firstname″}; $lastname=$form?data{″lastname″}; print ″Hello,$firstname $lastname. Thank you for your visit! ″;
• Servlet程序
public void service(HttpServletRequest request,HttpServletResponse response) throws ServletExeption,IOExeption { ServletOutputStreamout=response.getOutputStream(); response.setContentType(″text/html″); String firstname=request.getParameter(″firstname″); String lastname=request.getParameter(″lastname″); out.println(″Hello,″+firstname+″ ″+lastname+″.″); out.println(″Thank you for your visit!″); out.lose() }
可以很明显地看到Servlet源代码比相应的CGI程序(Perl)简单许多,可读性也好许多。这里需要导入3个package:javax.servlet、javax.servlet.http和java.io。
在CGI程序中需要耗费精力处理对参数的提取和解码,而在Servlet程序中,从HttpServlet类继承来的基本函数可以自动完成解码的过程。这将极大地减少程序员的劳动量和重复的代码劳动,并降低编码难度。
综上所述,Servlet在性能、编写难度、可移植性等方面比CGI有明显优势。
参考答案:
Servlet与CGI的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。