一、关于Servlet
在上一篇随笔中,我们看到了CGI存在的不足,其每次请求都需加载和运行一个CGI程序。若使用Java编写CGI程序,需要为每个请求都启动一个系统进程以及JVM,其执行效率大大降低。如果有办法取消这些开销,即只需要启动一个系统进程以及一个JVM映像,基于Java的CGI就能得到很好的改善。
Servlet就基于这种想法产生了,利用Java运行时可动态加载来处理新的请求,只需要启动一次服务器进程,只加载一次JVM,之后这个JVM再动态加载另外的类。其执行效率比传统CGI快得多了。Servlet的优点如下:
1、只需要启动一个系统进程以及加载一个JVM,大大降低系统开销。
2、如果多个请求需要做同样处理的时候,只需要加载一个类,这也大大降低开销。
3、所有动态加载的类可以实现对网络协议以及请求解码的代码共享,大大降低工作量。
4、Servlet能够直接和Web服务器交互,而普通的CGI不能。Servlet还能够在各个程序之间共享数据,使得数据库连接池之类的功能很容易实现。
5、Servlet是与平台无关的,因为它们是用Java编写的。
那究竟什么是Servlet呢? 简单地说:Servlet就是JAVA 类,是一个继承HttpServlet类的类,在服务器端运行,用以处理客户端的请求。现在的Web服务器(例如Tomcat)已经集成了Servlet容器,Servlet容器负责管理加载、卸载、重新加载和执行Servlet代码等操作。
具体来讲,Servlet是一种实现了javax.servlet.Servlet接口的类。Servlet接口规定了特定的方法来处理特定的请求。开发者只需要实现Servlet的相关方法,用户访问web程序时,Tomcat会调用这些方法来完成业务处理。Servlet扩展类javax.servlet.http.HttpServlet,实现Servlet接口和抽象类,它是专门设计用来处理HTTP请求。编写Servlet时直接继承HttpServlet,并覆盖需要的方法即可,一般只覆盖doGet()和doPost()方法。
二、Servlet工作流程
当用户访问服务器时,发送Request请求,由服务器(Tomcat)接收并解析,封装成HttpServletRequest类型的request对象,同时将输出流封装成HttpServletResponse类型的response对象,然后服务器(Tomcat)把request、response作为参数,调用Servlet的相应方法进行处理,例如doPost(request,response),doGet(request,response)等。
这里需简单了解HTTP规范,HTTP1.1规范支持OPTIONS、GET、POST、HEAD、PUT、DELETE以及TRACE等7中web访问方式。我们常用的有GET和POST。其中
·GET:表示查询信息,URL中可以附带少量的参数信息,但URL总长度不能超过256字符,并且参数会显示在浏览器地址栏。
·POST:表示提交信息,一般用于提交大量数据信息或者文件,提交的内容不受长度限制,并且不会显示在浏览器地址栏。
Java-Web请求响应过程如下图:
来看一个典型的Java Servlet代码
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); //设置向客户端发送的内容格式 PrintWriter out = response.getWriter(); //利用PrintWriter对象的方法将数据发送给客户端 out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.println(" Hello Servlet!"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); //这条语句的作用是,当客户端发送POST请求时,调用doGet()方法进行处理 } }
当用户请求该页面时,Servlet重复使用PrintWriter.println()方法来输出相应的HTML页面,以达到动态生成HTML页面的效果。
Servlet的配置文件为web.xml。这里涉及web程序在Tomcat上的部署,不详细展开,有关Java web环境的搭建(Myeclipse+Tomcat+MySQL)在下一篇随笔中详述。这里只展示一下配置文件。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>HelloServlet</servlet-name> <servlet-class>firstWeb.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/servlet/HelloServlet</url-pattern> </servlet-mapping> </web-app>
虽然Servlet改变传统CGI程序的缺点,但是它也有不足之处:Servlet生成网页的方法是在java类中嵌入HTML标签和表达式,也就是说对HTML做一个小小的改动时,需要修改和重新编译Servlet源文件,然后重新部署到Servlet容器中,这使得修改Servlet变得非常麻烦。
有兴趣的朋友可通过以下链接进一步学习:
1、易百Servlets教程:http://www.yiibai.com/servlets