ITEEDU

JSP/Servlet: 第一个Servlet程序

从Java程序设计人员的角度来看,Servlet其实就是一个Java类别,它实作 javax.servlet.Servlet接口,通常会继承实作该接口的javax.servlet.GenericServlet类别或javax.servlet.http.HttpServlet类别,前者用于与协议无关的Servlet,后者专门适于处理HTTP请求与响应的Servlet。

继承GenericServlet类别的Servlet通常会改写service()方法,而继承HttpServlet类别的 service()会处理request并传送给doXXX()方法,例如doGet()或doPost()方法,通常很少会去改写service(),而是改写doGet()或doPost()方法,下面就仍以一个简单的Hello!Servlet!来示范如何撰写与设定Servlet,让其可以传回一个 HTML网页显示Hello!Servlet!文字:

HelloServlet.java
package onlyfun.caterpillar;

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class HelloServlet extends HttpServlet { 
public void doGet(HttpServletRequest req, 
HttpServletResponse res) 
throws ServletException, IOException { 
res.setContentType("text/html"); 
PrintWriter out = res.getWriter(); 
out.println("<html>"); 
out.println("<head>");
out.println("<title>Hello!Servlet!</title>");
out.println("</head>"); 
out.println("<body>"); 
out.println("<h1><b>Hello!Servlet!</b></h1>"); 
out.println("</body>"); 
out.println("</html>"); 
} 
} 

为了要能编译上面这个类别,您需要将servlet-api.jar加至CLASSPATH中,在Tomcat的话servlet-api.jar是放在 common/lib目录下。

doGet()处理客户端请求的GET方法,只要是客户端请求资源时是使用GET方法,就会呼叫它来处理,它获得两个参数,分别表示客户端的请求与响应,您可以回忆一下JSP的隐含对象request与response,其对应的就是HttpServletRequest与 HttpServletResponse对象,您由HttpServletResponse对象取得写出至客户端的PrintWriter对象,并写出一个HTML网页至客户端,PrintWriter对象可以使用println()方法将资料写出。

假设您的Web应用程序位于webapps/myServlet/下,则编译完成的Servlet类别必须放置在WEB-INF/classes/之下,为了要让容器能知道这个Servlet的存在并实例化,您必须在WEB-INF/web.xml中告知:

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
version="2.4">
<description> 
My Servlet Examples. 
</description> 
<display-name>Servlet Examples</display-name>
<servlet> 
<servlet-name>hello</servlet-name> 
<servlet-class>
onlyfun.caterpillar.HelloServlet
</servlet-class> 
</servlet>
<servlet-mapping> 
<servlet-name>hello</servlet-name> 
<url-pattern>/helloServlet</url-pattern> 
</servlet-mapping>
</web-app> 

在容器实例化并初始化Servlet并给予相关环境对象之前,Servlet只不过是个普通的Java类别,并不具备有Servlet的该有的功能,容器 会为每一个注册的<servlet-name>实例化一个<servlet-class>指定的类别,而<url- pattern>用于指定与<servlet-name>对应的Servlet实例,经由这么指定,在启动 Tomcat之后,您可以透过这样的网址来执行Servlet:

http://localhost:8080/myServlet/helloServlet

当然,如果您想要的话,也可以在<url-pattern>中伪装Servlet,例如伪装为PHP网页,就设定为 /helloworld.php。

下面是Servlet的传回结果:

<html>
<head>
<title>Hello!Servlet!</title>
</head>
<body>
<h1><b>Hello!Servlet!</b></h1>
</body>
</html>

事实上,上面的程序只是为了示范而已,在MVC架构中,Servlet中是不会出现out.println()这样的陈述句的,在Servlet中撰写 HTML或视图相关的逻辑基本上是不被鼓励的,Servlet在 Model 2 架构中主要是担任控制者(Controller)的角色。

PS. 广义的来说,容器藉由使用者的请求网址决定该由哪一个Servlet来处理请求,本身也是控制器的角色,但实际上很少将容器用于控制器角色上,而是设计一个Servlet来处理请求转发,将控制器的角色由该Servlet担任。