Servlet的简单介绍
关于此文档中Servlet的内容基于Servlet 2.4。
关于环境:
运行Servlet不需要使用重量级的Java EE容器,故以下程序使用的开发运行工具为:
1、 Jdk 1.5.0 _15
2、 Tomcat 5.5.x
3、 Eclipse 3.3
关于tomcat:
为了方便验证修改过的servlet程序,将<tomcat installed dir>/conf/context.xml中的
<Context>
替换为:
<Context reloadable="true">
Eclispe新建项目名称为Servlet,源码文件夹为src,生产的class文件存放于classes目录,相中lib文件夹存放servlet-api.jar,并将此jar加入到项目的classpath中
Tomcat安装文件夹下的webapps文件夹中建立文件夹train,,train文件夹中建立文件夹WEB-INF,WEB-INF文件夹下建立classes和lib文件夹,并在WEB-INF下建立文件web.xml
web.xml中内容为:
< 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" >
</ web-app >
一、HttpServlet与 GenericServlet和Servlet的关系
public abstract class HttpServlet extends GenericServlet implements
Serializable
public abstract class GenericServlet extends Object implements Servlet,
ServletConfig, Serializable
由上面可以看出HttpServlet继承了GenericServlet,而GenericServlet则实现了Servlet接口。那就让我们从从Servlet这个接口开始看起吧。
Servlet接口包含的方法有init、getServletConfig、service、getServletInfo、destroy。
其中黑体字标注的3个方法和整个Servlet的生命周期有着很大的关系。
void init(ServletConfig config) throws ServletException
当一个实现了Servlet接口的类的对象被初始化后会先执行init方法(这一点说明Servlet在响应用户请求之前肯定会先执行init这个方法,所以我们假如需要的话,可以在这个方法的实现中获取一些资源来为将来相应用户的请求做准备)。
init方法的参数只有一个config类型为ServletConfig。这个参数中包含了运行Servlet的容器在这个Servlet被初始化使用传递给ServletConfig的信息。(关于ServletConfig的相关内容在后面会有所提及)
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
每当用户的一个请求上来之后,Servlet容器会调用servlet对象(这个词不够准确,准确的说是实现了Servlet接口的类的一个实例)的service方法来响应用户的请求。容器会将用户的请求封装成一个ServletRequest对象,将相应用户请求的内容封装成ServletResponse对象。
void destroy()
当servlet容器认为不在需要一个servlet对象的时候会调用这个方法。当然一般的情况下servlet容器调用这个方法的时候一般是servlet容器需要停止,或者产生了过多的servlet对象的时候(关于这个问题在后面会有所提及)。
简单的说,我们可以使用这个方法达到释放一些资源的目的。
ServletConfig getServletConfig()
返回当前servlet对象的ServletConfig。这里有一些需要注意的地方,假如我们直接通过实现Servlet这个接口来写一个类提供服务的话,我们如果不想这个方法返回null的话,我们唯一能做的只有在void init(ServletConfig config)中使用一个成员变量来保存config这个传进来的参数。
String getServletInfo()
这个方法。。。只能说想返回什么就返回什么吧。
下面举一个简单的例子来说明下Servlet这个接口
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServletTest implements Servlet
... {
private ServletConfig config = null;
private PrintWriter out = null;
public ServletTest()
...{
try
...{
out = new PrintWriter(new FileOutputStream("C:/Servlet.log")); /**//* 将C:/Servlet.log替换成你想查看的文件路径 */
} catch (FileNotFoundException e)
...{
e.printStackTrace();
}
out.write("ServletTest() " + System.getProperty("line.separator"));
out.flush();
}
public void destroy()
...{
out.write("destroy() " + System.getProperty("line.separator"));
out.close();
}
public ServletConfig getServletConfig()
...{
return config;
}
public String getServletInfo()
...{
return "author is squall";
}
public void init(ServletConfig servletConfig) throws ServletException
...{
this.config = servletConfig;
out.write("init(ServletConfig servletConfig) "
+ System.getProperty("line.separator"));
out.flush();
}
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
...{
out.write("service(ServletRequest request, ServletResponse response) "
+ System.getProperty("line.separator"));
out.flush();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType = "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ";
out.println(docType + "<HTML> "
+ "<HEAD><TITLE>Hello from Servlet</TITLE></HEAD> "
+ "<BODY BGCOLOR="#FDF5E6"> "
+ "<H1>Hello World from Servlet!</H1> " + "</BODY> "
+ "</HTML>");
}
}
部署(关于部署的内容就简单介绍一次,除非以后有特别需要说明的地方):
将eclipse项目中的classes文件夹下的内容拷贝到tomcat/webapps/train/WEB-INF/classes下。并修改tomcat/webapps/train/WEB-INF/web.xml为
< 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" >
< servlet >
< servlet-name > squall.servlet.basic.ServletTest </ servlet-name >
< servlet-class > squall.servlet.basic.ServletTest </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > squall.servlet.basic.ServletTest </ servlet-name >
< url-pattern > /Servlet </ url-pattern >
</ servlet-mapping >
</ web-app >
蓝色部分为新添加的内容。
<servlet>
<servlet-name>squall.servlet.basic.ServletTest</servlet-name><!--servlet-name为servlet的名字-->
<servlet-class>squall.servlet.basic.ServletTest</servlet-class> <!--servlet-class为此servlet的具体的实现类-->
</servlet>
<servlet-mapping>
<servlet-name>squall.servlet.basic.ServletTest</servlet-name> <!--servlet-name为servlet的名字,应该与上面的servlet-name保持一致-->
<url-pattern>/Servlet</url-pattern><!-- url-pattern为servlet mapping到的url-->
</servlet-mapping>
其中/url-pattern的值为将来访问的url的地址。这个值里面可以包含*这样的符号,*表示匹配所有。
<url-pattern>/Servlet</url-pattern>
表示我们通过http://127.0.0.1:8080/train/Servlet就可以访问这个应用。
假如url-pattern为<url-pattern>/a/*</url-pattern>的话,则代表无论是
http://127.0.0.1:8080/train/a/z
http://127.0.0.1:8080/train/a/c/d
都可以与之匹配
以后添加新的Servlet的时候只需要在最后一个</servlet-mapping> 下添加一个新的
<servlet>
<servlet-name>squall.servlet.basic.ServletTest</servlet-name>
<servlet-class>squall.servlet.basic.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>squall.servlet.basic.ServletTest</servlet-name>
<url-pattern>/Servlet</url-pattern>
</servlet-mapping>
结构即可。
部署完毕,启动tomcat,以后访问http://127.0.0.1:8080/train/Servlet页面会看到
屏幕上输出
Hello World from Servlet!
关掉当前ie窗口后,再次访问http://127.0.0.1:8080/train/Servlet,后停止tomcat,会在
C:/Servlet.log中看到如下输出
ServletTest()
init(ServletConfig servletConfig)
service(ServletRequest request, ServletResponse response)
service(ServletRequest request, ServletResponse response)
destroy()
可以看到输出符合上面的方法的介绍。