Servlet从第一个访问者开始,就创建了,创建的时候,先调用构造函数,然后再调用Init函数进行初始化。当第一次创建的servlet时候,调用init方法,对servlet进行初始化,因此,如果你开发的servlet需要进行一些其他的初始化的时候,就应该在init中写代码。在此之后,在每个用户请求结果线程中调用之前创建的servlet实例的service方法。因此多个并发的请求会同时调用service方法。当然,可以让servlet实现SingleThreadModel这个特殊的接口,从而保证在任何时候,都只有一个线程可以调用service方法。service方法根据收到的HTTP的请求类型分别调用doGet、doPost,或其他的do***方法。当停止服务的时候,调用destroy函数销毁。
一、Service方法
每当服务器接收到一个servlet请求的时候,服务器就会分配一个新的线程,由该线程调用service方法。service方法检查HTTP请求的类型(包括GET、POST、PUT、DELETE等),并且分别调用doGet,doPost,doPut,doDelete等。
如果你需要同时处理GET和POST的话,那么你可能会选择直接重写覆盖service方法的做法,当然这种做法也是可以的。但是更好的做法是只重写覆盖doGet或者doPost,然后在其中一个里面处理另外一个方法。如:
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
{
// Servlet code
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
这样做有如下几个好处:
1、你可以在以后需要的时候,增加doPut,doTrace等方法;如果重写覆盖service方法,将导致无法处理。比如说,继承该类的子类中就无法完成了。
2、可以通过添加getLastModified方法来完成日期的修改。因为getLastModified是被默认的service方法调用的。
3、service方法是自动支持HEAD、OPTION、TRACE等请求的。
二、do***方法
在绝大部分时候,我们编写servlet只需要注意doGet和doPost方法即可。
三、init方法
init方法有两个版本,一种是不带参数的,一种是带参数的。
public void init() throws ServletException {
// Initialization code...
}
public void init(ServletConfig config) throws ServletException
{
// Initialization code...
}
注意,带参数的init方法中,ServletConfig所指向的文件就是发布该servlet的web应用的web.xml文件。编写带参数的servlet例子如下:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloServlet extends HttpServlet//第一步:扩展HttpServlet抽象类
{
private static final long serialVersionUID = 1L;
private String Param1 = "";
private String Param2 = "";
private String Param3 = "";
public void init(ServletConfig config) throws ServletException
{
super.init(config);
Param1 = config.getInitParameter("param1");
Param2 = config.getInitParameter("param2");
Param3 = config.getInitParameter("param3");
}
//第二步:覆盖doGet()方法
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException,ServletException{
//第三步:获取HTTP请求中的参数信息
String clientName=request.getParameter("clientName");
if(clientName!=null)
clientName=new String(clientName.getBytes("ISO-8859-1"),"GB2312");
else
clientName="我的朋友";
//第四步:生成HTTP响应结果
PrintWriter out;
String title="HelloServlet";
String heading1="HelloServlet的doGet方法的输出:";
//set content type
response.setContentType("text/html;charset=GB2312");
//write html page
out=response.getWriter();
out.print("<HTML><HEAD><TITLE>"+title+"</TITLE>");
out.print("</HEAD><BODY>");
out.print(heading1);
out.println("<h1><p>"+clientName+":您好</h1>");
out.println("<h1><p>Param1:"+Param1+"</h1>");
out.println("<h1><p>Param2:"+Param2+"</h1>");
out.println("<h1><p>Param3:"+Param3+"</h1>");
out.print("</BODY></HTML>");
out.close();
}
}
发布该servlet的时候,需要对web.xml做修改:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
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">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>test param1</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>test param2</param-value>
</init-param>
<init-param>
<param-name>param3</param-name>
<param-value>test param3</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
注意:<load-on-startup>1</load-on-startup>中,如果带了参数,就必须有,否则无法执行init带参数的方法,其中的整数是启动该servlet的先后顺序,如果是负数或者没有这个标签,则服务器在启动时不自动加载这个servlet,如果是0或者正数,服务器启动时就必须加载了。
四、destroy方法
该方法是当服务器决定移除某个已经存在的servlet实例的时候执行,在该方法中,可以对一些资源进行释放处理。