1.Servlet的生命周期
(1)什么是servlet的生命周期?
容器如何去创建servlet对象,如何对该对象进行初始化,如果调用该
对象处理请求,以及如何销毁该对象的整个过程。
即Servlet容器是如何去管理Servlet的。
(2)生命周期分成哪几个阶段?
1)实例化
a.何为实例化?
容器调用servlet的构造器,创建servlet对象。
b.什么时候实例化?
情形1:默认情况下,容器收到请求之后,才会创建。
注:
容器只会创建一个实例。
情形2:容器启动之后,立即创建。
注:
需要配置load-on-startup参数。
<!--
配置启动加载(容器启动之后,会立即创建servlet实例)。
参数值是一个大于或者等于零的整数,
值越小越先被创建。
-->
<load-on-startup>1</load-on-startup>
2)初始化
a.何为初始化?
容器在创建servlet实例之后,会调用该实例的
init(ServletConfig config)方法。
注:
init方法只会执行一次!
b.GenericServlet已经提供了init方法的实现。
该方法会将容器传递过来的ServletConfig对象保存下来,并且
提供了一个方法(getServletConfig)来获得该对象。
c.如何实现自已的初始化处理逻辑。
只需要override GenericServlet的init()方法。
d.初始化参数。
<!--
配置初始化参数
-->
<init-param>
<param-name>company</param-name>
<param-value>IBM</param-value>
</init-param>
/*
* 通过ServletConfig对象提供的方法来
* 读取初始化参数。
*/
String company =
config.getInitParameter("company");
3)就绪
a.何为就绪?
容器收到请求之后,调用servlet对象的service方法。
b.HttpServlet已经提供了service方法的实现。
该方法是这样实现的:
依据请求类型调用对应的doXXX方法,比如,get请求会调用
doGet方法,post请求会调用doPost方法。
doGet、doPost方法只是抛出了一个异常。
开发人员可以override HttpServlet的doXXX方法来实现
业务逻辑的处理。也可以override HttpServlet的service
方法。
4)销毁
a.何为销毁?
容器在删除servlet对象之前,会调用该对象的destroy方法。
注:
该方法只会执行一次!
b. GenericServlet已经提供了destroy方法的实现。
注:
该方法的实现实际上什么都没有做。
开发人员可以override GenericServlet提供的destroy
方法,来实现自己的销毁处理逻辑。
(3)相关的接口与类。
a.Servlet接口
注:该接口主要声明了三个方法
init(ServletConfig config);
service(ServletRequest req,ServletResponse res);
destroy();
b.GenericServlet抽象类
注:实现了Servlet接口中的部分方法(init,destroy)。
c.HttpServlet抽象类
注:继承了GenericServlet,实现了service方法。
以下补充:
2.容器如何处理请求资源路径?
比如,在浏览器地址栏输入http://ip:port/day08-2/abc.html,
浏览器会将"/day08-2/abc.html"作为请求资源路径发送给容器。
step1.容器默认认为访问的是一个servlet,容器会从web.xml中去
查找对应的servlet。
会将请求资源路径中的应用名除掉,然后去跟<url-pattern>
的值去做匹配。
url-pattern有三种写法:
精确匹配:
即请求资源路径除掉应用名之后的值必须等于url-pattern的值。
(比如这儿,请求资源路径除掉应用名之后是
"/abc.html",url-pattern的值正好也是"/abc.html",这样
就匹配了)
通配符匹配:
使用"*"匹配任意的零个或者多个字符。
比如:
<url-pattern>/*</url-pattern>
<url-pattern>/demo/*</url-pattern>
后缀匹配:
使用"*."开头,然后接一个后缀(后缀就是一个字符串)。
比如:
<url-pattern>*.do</url-pattern>
以上配置,会匹配所有以.do结尾的请求。
<url-pattern>*.action</url-pattern>
step2.如果没有匹配的servlet,容器会从对应的位置去查找文件,
如果找不到,返回404。
3.如何让一个servlet处理多种请求?
step1.使用后缀匹配,比如:
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
step2.分析请求资源路径,依据请求路径进行相应的处理,比如:
//获得请求资源路径
String uri = request.getRequestURI();
System.out.println("uri:" + uri);
/*
* 分析请求资源路径(为了方便比较,
* 这儿截取请求资源路径的一部分)。
*/
String path =
uri.substring(
uri.lastIndexOf("/"),
uri.lastIndexOf("."));
System.out.println("path:" + path);
//依据请求路径(path)进行相应的处理。
if("/list".equals(path)){
System.out.println("处理用户列表的请求...");
}else if("/add".equals(path)){
System.out.println("处理添加用户的请求...");
}