作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
在中,我们搭建了用于测试Servlet和JSP的基本环境。我们现在要转向网络应用的具体开发。
厨师
Web服务器的基本工作方式是请求-处理-回复。请求和回复是在网络上,以HTTP协议为基础的通信(参考)。请求是客户点菜,回复像是服务员上菜,而处理则是在后厨中,厨师根据请求的菜单,准备菜品的过程。
厨师通常是服务器上的一个应用程序。这个应用程序可以提取请求中的信息,并根据这些信息准备回复。这样的应用程序可以是许多中语言写成的,比如C, C++, Perl, Ruby, Python, Ruby, PHP等等。由于不同语言的设计理念和编译器特征的不同,这些语言写成的应用程序也有不同的特点(各种各样的厨师)。比如C和C++语言会有比较高的运行效率,PHP的Web应用广泛,Ruby和Python开发方便等等。
(在语言之争中,Web服务器的“后厨”是一块兵家必争之地)
Servlet是Java语言提供的的“厨师”。在Java中,“一切皆对象”。Servlet是一类特殊的Java对象。Java语言利用Servlet对象,来实现对HTTP请求的处理。
样例
下面是一个简单的Servlet例子,源文件为TestPage.java:
package foo;import javax.servlet.*;import javax.servlet.http.*;import java.io.*;public class TestPage extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { PrintWriter out = response.getWriter(); out.println("" + "Hello World!
" + ""); }}
这个Servlet的功能是回复字符串"<html><body><p>Hello World!</p></body></html>"。这一段字符串实际上是一个HTML文本。它将作为HTTP回复的主体部分,发回给客户端。
这里定义了一个TestPage类,该类继承HttpServlet抽象类(参考)。我们覆盖了doGet()方法。doGet()方法处理GET方法的HTTP请求。如果HTTP请求的方法为POST,则应该覆盖doPost()方法。每个Servlet都应该覆盖doGet()和doPost()之一。doGet()和doPost()方法接收两个参数request和response,分别为HttpServletRequest类型和HttpServletResponse类型。这两个参数分别代表该次HTTP通信的请求和回复。
HttpServletRequest和HttpServletResponse为两个接口。在方法的内部,我们可以操作request和response对象。比如,通过response的getWriter方法,来获得Writer,从而写入HTML文本。这些写入的文本将作为HTTP回复的主体传递回客户端。再比如,我们可以使用request的getMethod()方法来获知HTTP请求的方法。可以参考下面的官方文档:
此外,来自java.io包。参考
doGet()是真正的工作室。我们通过定义该方法(或者doPost())方法,来让厨师做特定的事情。Servlet编写的关键在于写出一个符合需求的doGet()方法或者doPost()方法。
doGet()与doPost()
正如第一行package语句所说明的(参考),TestPage类被放入到foo包中。我们还import了其他的Java包。Servlet是基于Java的,所以它可以借助Java语言所提供的丰富的工具。
编译
使用下面命令编译TestPage.java
$javac -classpath /path-to-tomcat/lib/servlet-api.jar:classes:. TestPage.java
上面的path-to-tomcat是Tomcat的安装路径。我们需要包括servlet-api.jar,原因是,javax.servlet包属于J2EE,它并不属于JSE。
将编译生成的TestPage.class文件放入到下面的文件夹中。(如果文件夹不存在,需要自行创建):
/path-to-tomcat/webapps/test/WEB-INF/classes/foo
(在TesPage.java中,利用package语句,说明该类在foo包中。这里的路径符合之前的package定义。)
修改或者新建/path-to-tomcat/webapps/test/WEB-INFO/web.xml
Test foo.TestPage Test /MyServlet
这样的一个xml文件被称作部署描述(DD, Deployment Descriptor)。DD告诉Container如何运行Servlet和JSP。
上面的<servlet>标签是将该Servlet(foo.TestPage.class)命名为Test。
在<servlet-mapping>标签中,我们将Test这个Servlet对应于URL: /MyServlet。这说明,当有请求访问该URL时,则将请求传递给Test这个Servlet处理。
上面修改的主要目的,是说明Servlet与URL的对应关系。
随后,可以访问localhost:8080/test/MyServlet,来查看访问页面。
过程
看一下Servlet完成一次请求处理的过程:
从客户端(Guest)向服务器发送HTTP请求,该HTTP请求传递给Servlet Container。该Container负责:
- 分析HTTP请求的信息,并新建request对象,将HTTP请求中的信息放入request对象
- 新建response对象
- 根据web.xml,查找URL对应的Servlet对象。如果Servlet对象不存在,则新建相应Servlet对象。
- 创建新的线程,用于处理本次请求。线程拥有指向request和response对象的引用。
线程将调用Servlet的doGet()或者doPost()方法。线程运行结束后,response对象将传回给Container。Container根据response对象中的信息,生成一个符合HTTP协议的回复,传回给客户端。
注意,即使是新建的Servlet对象,它也不会随着线程的结束而结束。Servlet将继续存在。下次相同的URL访问将不必新建Servlet。
总结
上面制作了一个简单的Servlet,主要用于说明制作Servlet的过程。Servlet的许多强大功能还有待以后展开。
每个Servlet就像是后厨的一个厨师。我们可以用不同的URL对应来选择不同的厨师。一个复杂的网站往往需要许多个不同功能的Servlet。
欢迎继续阅读“”系列文章