一、Servlet的继承层次
Servlet接口:
//Servlet接口的定义
package javax.servlet;
import java.io.IOException;
public interface Servlet{
//创建Servlet实例后调用的初始化方法
public void init (ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
//处理客户端请求的方法
public void service (ServletRequest request, ServletResponse response)
throws ServletException, IOException;
public String getServletInfo();
//销毁Servlet实例前调用的方法
public void destory();
}
GenericServlet抽象类:
GenericServlet实现了Servlet中除了sevice方法外的其他4个方法。
HttpServlet抽象类:
HttpServlet实现了GenericServlet中的service方法,并通过service方法将处理HTTP的不同方法的工作交由 相应的方法处理,如doGet、doPost。
虽然HttpServlet是一个抽象类,但是它不包含任何抽象方法。
MyServlet类:
我们自己定义的Servlet,继承自HttpServlet。
二、Servlet的配置
1、利用@WebServlet annotation进行配置
@WebServlet的常用属性
//可选属性,指定该Servlet是否支持异步操作模式。
asyncSupported
//可选属性,指定该Servlet的显示名。
displayName
//可选属性,用于为该Servlet配置参数。
initParams
//可选属性,用于将该Servlet配置成load-on-startup的Servlet。
loadOnStartup
//可选属性,指定该Servlet的名字。
name
//可选属性,指定该Servlet处理的URL
urlPattern/value
示例:
@WebServlet(name = "testServlet"
, urlPattern = {"/testServlet"}
, loadOnStartup = 1
, initParams = {
@WebInitParam(name = "driver", value = "com.mysql.jdbc.Driver"),
@WebInitParam(name = "url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name = "name", value = "root"),
@WebInitParam(name = "pwd", value = "root")
})
public class TestServlet extends HttpServlet{
}
注意:
如果使用Annotaion来配置Servlet,就不要在web.xml文件的根元素(web-app)中指定metadata-complete="true",也不要在web.xml文件中配置该Servlet。
2、利用web.xml文件进行配置
<servlet> <!--指定Servlet的名字,相当于@WebServlet的name属性--> <servlet-name>testServlet</servlet-name> <!--指定Servlet的实现类--> <servlet-class>org.lgy.servlet.TestServet</servlet-class> </servlet> <servlet-mapping> <!--指定Servlet的名字,与上面定义的名字相同--> <servlet-name>testServlet</servlet-name> <!--指定Servlet映射的URL,相当于@WebServlet的urlPatterns属性--> <url-pattern>/testServlet</url-pattern> </servlet-mapping>
三、Servlet的生命周期
- 创建Servlet实例
- 调用init方法进行初始化
- Servlet初始化后,将一直存在于内存中(仅初始化一次),一直等待响应客户端的请求,直至被销毁。
- Web容器决定销毁Servlet时,调用destroy方法,回收资源。
四、创建Servlet的时机
创建Servlet实例有2个时机:
- 客户端第一次请求某个Servlet时,容器创建该Servlet的实例,这是绝大部分Servlet被创建的时机。这种类型的Servlet无需额外的配置。
- 容器启动时立即创建Servlet实例,即load-on-startup Servlet。这类Servlet需要配置load-on-startup属性。
//loadOnStartup属性指定该Servlet在容器启动后立即实例化,数值越大,优先级越高
@WebServlet(loadOnStartup = 1)
public class TestServlet extends HttpServlet{
}
<servlet> <!--指定Servlet的名字,相当于@WebServlet的name属性--> <servlet-name>testServlet</servlet-name> <!--指定Servlet的实现类--> <servlet-class>org.lgy.servlet.TestServet</servlet-class> <!--设置该Servlet在容器启动后立即实例化,数值越大,优先级越高--> <load-on-startup>1</load-on-startup> </servlet>
五、为Servlet配置参数
1、配置参数
1:@WebServlet
@WebServlet(name = "testServlet"
, urlPattern = {"/testServlet"}
, loadOnStartup = 1
, initParams = {
@WebInitParam(name = "driver", value = "com.mysql.jdbc.Driver"),
@WebInitParam(name = "url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name = "name", value = "root"),
@WebInitParam(name = "pwd", value = "root")
})
public class TestServlet extends HttpServlet{
}
2、web.xml
<servlet> <!--指定Servlet的名字,相当于@WebServlet的name属性--> <servlet-name>testServlet</servlet-name> <!--指定Servlet的实现类--> <servlet-class>org.lgy.servlet.TestServet</servlet-class> <!--配置参数--> <init-param> <param-name>driver</param-name> <param-vlaue>com.mysql.jdbc.Driver</param-value> </init-param> <init-param> <param-name>url</param-name> <param-vlaue>jdbc:mysql://localhost:3306/javaee</param-value> </init-param> <init-param> <param-name>name</param-name> <param-vlaue>root</param-value> </init-param> <init-param> <param-name>pwd</param-name> <param-vlaue>root</param-value> </init-param> </servlet> <servlet-mapping> <!--指定Servlet的名字,与上面定义的名字相同--> <servlet-name>testServlet</servlet-name> <!--指定Servlet映射的URL,相当于@WebServlet的urlPatterns属性--> <url-pattern>/testServlet</url-pattern> </servlet-mapping>
2、获取参数
public void service(HttpServletRequest request, HttpServletResponse)
throws ServletException, IOException
{
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String name = config.getInitParameter("name");
String pwd = config.getInitParameter("pwd");
//...... ......
}
六、Servlet处理客户端请求的流程
1、获取请求的URL
在接收到客户端的HTTP请求后,Servlet引擎获得了一个URL,假设请求的URL如下:
http://localhost:8080/sample/FirstServlet
Servlet引擎从上述URL中提取了/sample和/FirstServlet
2、查找Web应用路径
在<Tomcat安装目录>\conf\server.xml中查找path为“/sample”的<Context>标签,找到后,获得docBase
所指定的Web应用的目录
3、根据web.xml查找请求的Servlet
根据上一步找到的Web应用的目录,找到web.xml并读取其中的内容。将从请求URL中提取的/FirstServlet和<servlet-mapping>中的<url-pattern>进行比较,如果发现相匹配的<url-pattern>,就可以获得相应的Servlet类。
4、创建Servlet实例
如果上一步获得了相应的Servlet,Servlet引擎就会动态装载这个Servlet类,并创建Servlet实例。
5、提供服务
在调用Servlet的service方法提供服务之前,Servlet引擎会先调用init方法初始化Servlet。之后才会调用service方法提供服务。
6、卸载Servlet
当容器停止或重新启动前,Servlet引擎会卸载容器中所有的Servlet,并调用每个Servlet的destroy方法。
注意:
1、对于不同Servlet的启动顺序可以通过load-on-startup属性指定。这个属性的值为0或正整数,数值越 大,优先级越高。如果该属性的值为负数或相同,则由Servlet引擎决定先装载哪个Servlet。
2、Servlet在装载后就常住内存。
3、在默认情况下,当开发人员对Servlet进行了修改,除非重新启动Tomcat,否则Servlet引擎还是执行 内存中的Servlet对象实例。如果想在不重新启动Tomcat的情况下感知Servlet的变化,可以通过<Context>标签的reloadable属性来设置。如下:
<Context path="/sample" docBase="d:\sample" debug="0" reloadable="true"/>