Servlet的生命周期:
init方法。
只会被初始化一次。由容器初始化。初始化成功后将缓存于容器中。
它的初始时间分为两种:
用户第一次访问时。
服务器启动时。-需要配置。
service方法
每次请求都会访问此方法。
每次请求都会创建新的Request和Response对像。
destory方法
当服务器关闭时由容器调用并销毁。
Servlet初始化图解(简化):
三种开发方式需要的web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>ServletDemo1</display-name>
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>cn.hcnu.servlets.OneServlet</servlet-class>
<!-- init-param 初始化参数 -->
<init-param>
<param-name>charset</param-name>
<param-value>utf-8</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>OneServlet_2</servlet-name>
<!-- 与上面的servlet是同一个类,但是是不同的对象 -->
<servlet-class>cn.hcnu.servlets.OneServlet</servlet-class>
<!-- load-on-startup 值越小,越优先加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>cn.hcnu.servlets.TwoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ThreeServlet</servlet-name>
<servlet-class>cn.hcnu.servlets.ThreeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>OneServlet_2</servlet-name>
<url-pattern>/one2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ThreeServlet</servlet-name>
<url-pattern>/three</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
第一种开发方式:实现Servlet接口
package cn.hcnu.servlets;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* servlet生命周期:
* 第一次访问该servlet时执行一次构造方法,一次init方法,一次service方法
* 第2~n次访问该servlet时就只执行service方法
* 在服务器Tomcat,stop时调用一次destroy方法
*
*
* @author 宋进宇 Email:[email protected]
*/
public class OneServlet implements Servlet {
public OneServlet() {
System.out.println("OneServlet---构造函数---"+this);
}
@Override
public void init(ServletConfig config) throws ServletException {
String charset = config.getInitParameter("charset");
System.out.println("init---初始化配置参数---"+this);
System.out.println("charset:"+charset);
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("service---"+this);
}
@Override
public void destroy() {
System.out.println("destroy---"+this);
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
第二种开发方式:继承GenericServlet类,类似适配器的用法
注意:覆盖init方法时,需要小心。
package cn.hcnu.servlets;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@SuppressWarnings("serial")
public class TwoServlet extends GenericServlet {
/*
* 覆盖init(ServletConfig config)方法时,
* 需要在第一句调用super.init(config),
* 不然web.xml中配置的初始参数没法使用,
* 如果需要在init时做些事情,最后覆盖init()空参的方法,
* 这是包装类/适配器类设计思想,把一些复杂的事情做了,
* 如果使用者需要补充再覆盖可覆盖的方法如本例的init()空参的方法。
*/
/*@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init---初始化配置参数---"+this);
}*/
@Override
public void init() throws ServletException {
System.out.println("do something...");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("service---"+this);
}
}
第三种开发方式:继承HttpServlet,最常用
package cn.hcnu.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class ThreeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost...");
}
}
GenericServlet VS HttpServlet对比分析:
GenericServlet
•为Servlet提供的通用的实现。
•它与任何网络应用层协议无关。见它的service方法的参数:ServletRequest,ServletResponse.
•GenericServlet实现了init(ServletConfig)方法并提供了getServletConfig()方法以获取此方法。并调用了另一个init()方法,通常需要子类覆盖init()方法,如果覆盖init(ServletConfig)方法,则在第一句必须super.init(config)调用父类的方法。
•同时提供了init()空参数的方法子类可以覆盖。
•此类实现了ServletConfig接口。
HttpServlet
•此类为Servlet接口提供了与HTTP协议相关的通用实现,也就是说,HttpServlet对像适合运行在客户端采用HTTP协议通信的Servlet容器或Web容器中。建议扩展此类完成你的Servlet。
•HttpServlet将客户的HTTP请求分为:doGet,doPost。在HttpServlet的内部,它首先实现父类的service方法,然后将ServletRequest和ServletResponse强制类型转换为HttpServletRequest和HttpServletResponse,再通过request.getMethod()判断转向执行不同的方法。
•因此子类可应该实现 doPost,doGet方法,如果子类没有实现则HttpServlet默认和向服务器返回一个错误为405的错误,即方法没有找到的错误。
•实现doPost和doGet重用可在doGet中调用doPost。