Schema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--web.xml文件主要用来配置该web应用使用到的Servlet-->
<!--配置HelloServlet-->
<!--解读:
1.servlet-name:给Servlet取名(任意),该名字唯一
2.servlet-class:Servlet的类的全路径,Tomcat在反射生成该Servlet类实例时需要使用
3.servlet-mapping里的servlet-name要和上面的servlet-name保持一致
4.url-pattern:这个就是该Servlet访问的url的配置(路径)
5.这时我们应该这样访问Servlet:http://localhost:8080/web应用名/helloServlet
6.url-pattern的取名也是随意的(注意加上斜杠)
-->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.li.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
设置 快捷键ctrl+/ 可以在当前位置注释,而不是在行
访问HelloServlet(记得要reploy或者restart)
可以自己配置快捷键启动
浏览器访问:
后台输出:可以看到init方法只调用了一次,而每次访问都会调用server方法
4.浏览器调用Servlet流程分析
注意这里的第几次请求是值对于Tomcat而言,并不在乎是哪个浏览器
-
首先查询web.xml文件
-
看看请求的资源/helloServlet在web.xml有没有配置url-pattern
-
如果找到url-pattern,就会得到对应的servlet-name:HelloServlet
-
Tomcat维护了一个大的HashMap<id,Servlet>,查询该HashMap,看看有没有这个Servlet实例
-
如果没有查询到该servlet-name对应的id,即没有这个Servlet实例
-
就根据servlet-name去得到servlet-class:类的全路径
-
使用反射技术,将servlet实例化(同时调用init方法),并将该实例放入到Tomcat维护的HashMap<id,Servlet>中
-
首先查询web.xml文件
-
看看请求的资源/helloServlet在web.xml有没有配置url-pattern
-
如果找到url-pattern,就会得到对应的servlet-name:HelloServlet
-
Tomcat维护了一个大的HashMap<id,Servlet>,查询该HashMap,看看有没有这个Servlet实例
-
如果查询到,就直接调用该Servlet的service方法
-
结果处理
-
前面说到Servlet是单例的,现在来证明:
在实现的Servlet类HelloServlet中增加一个count属性
在service方法中,增加语句count++;
并将其输出,如果每次输出的count是累加的,就说明每一次请求使用的都是同一个Servlet实例
使用浏览器访问:
后台输出:(在切换不同的浏览器访问后,count的值仍是累加的)
5.Servlet生命周期
- init() 初始化阶段
- service() 处理浏览器请求阶段
- destroy() 终止阶段
-
示意图
5.1初始化阶段-init()
Servlet容器(比如Tomcat)加载Servlet,加载完之后,Servlet容器会创建一个Servlet实例并调用init()方法,init方法只会调用一次,Servlet容器在下面的情况装载Servlet
-
Servlet容器(如Tomcat)启动时自动装载某些servlet,实现这个需要在web.xml文件中添加
<load-on-startup>1</load-on-startup>
<!--1表示装载的顺序,比如在-->
-
在Servlet容器(如Tomcat)启动后,浏览器首次向Servlet发送请求
-
Servlet重新装载时(比如tomcat进行redeploy),浏览器再向Servlet发送请求的第1次
redeploy会销毁所有的Servlet实例
例子1:<load-on-startup>1</load-on-startup>
在web.xml文件中添加<load-on-startup>1</load-on-startup>
之后,重新启动tomcat,可以看到,在没有浏览器发送请求的情况下,调用了init方法,这说明该Servlet已经被装载
例子2:Servlet重新装载时(比如tomcat进行redeploy),浏览器再向Servlet发送请求的第1次会装载Servlet
后台显示状况:
说明redeploy后Servlet实例被销毁了,当浏览器再次请求时,Tomcat会重新装载Servlet,因此init方法再次被调用
5.2处理浏览器请求阶段-service()
- 每收到一个http请求,服务器就会产生一个新的线程去处理
- 创建一个用于封装HTTP请求消息的ServletRequest对象和一个代表HTTP响应消息的ServletResponse对象
- 然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去
例子1:验证是否每收到一个http请求,服务器就会产生一个新的线程处理
在service方法中输出当前线程的id
浏览器请求Servlet时后台的输出:
5.3终止阶段-destroy()
当web应用被终止,或者Servlet容器终止运行,或者Servlet类重新装载时,会调用destroy方法(很少使用)
比如重启Tomcat,或者redeploy web应用
例子
在destroy方法中输出提示
重启Tomcat,在浏览器访问Servlet(让Servlet类加载),然后选择