1.url_pattern匹配模式
2.servlet生命周期
3.servlet线程问题
一、url_pattern
1.定义:
当浏览器发起一个url请求后,该请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url。例如:
(上一篇文章的地址)http://localhost:8080/TestServlet/First
localhost: 到本地的hosts文件中查找是否存在该域名对应的IP地址
8080: 找到tomcat服务器
/TestServlet 在tomcat的webapps目录下找 TestServlet 的目录
剩下的/First部分拿来做servlet的映射匹配。这个映射匹配过程是有优先顺序的。
2.分类
这里主要分为精确匹配和模糊匹配。
精确匹配 /first http://localhost:8080/TestServlet/First
/First/demo1 http://localhost:8080/TestServlet/First/demo1
模糊匹配 /* http://localhost:8080/TestServlet/任意路径
/First/* http://localhost:8080/TestServlet/First/任意路径
*.后缀名 http://localhost:8080/TestServlet/任意路径.do
*.do
*.action
*.html(伪静态)
注意事项:
1.匹配的时候,以精确匹配-->模糊匹配-->后缀名匹配这样的优先级进行匹配。
2.以匹配模式相似最高的优先。
3.只能以 / 或者 * 开头。
假设例子:
Servlet1 映射为 /a/*
Servlet2 映射为 /*
Servlet3 映射为 /a
Servlet4 映射为 *.do
请求为:/a/a.html 1,2,3都匹配,但优先匹配Servlet1
请求为:/a 1,2,3都匹配,但优先匹配Servlet2
请求为:/a/a.do 1,2,4都匹配,但优先匹配Servlet1
请求为:/a.do 2,4都匹配,但优先匹配Servlet2
4.如果在这里的pattern找不到,会交由缺省路径来匹配资源。缺省静态路径是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。注意:先加载动态资源(web.xml)里面的资源,然后再查找静态资源。
二、Servlet的生命周期
1.定义
Servlet生命周期:研究Servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。这些都是由服务器Tomcat来控制的
Servlet 生命周期可被定义为从创建(第一次访问Servlet)直到毁灭的整个过程。以下是 Servlet 遵循的过程:
- Servlet 通过调用 init () 方法进行初始化。 (创建完对象的时候调用一次)
- Servlet 调用 service() 方法来处理客户端的请求。 (每次请求调用一次)
- Servlet 通过调用 destroy() 方法终止(结束)。 (销毁sevlet对象调用,发生在停止服务器或者重新部署服务器的时候)
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
2.描述过程:
1°.首先浏览器发起一个http请求,Tomcat根据连接通过url-patern找到对应的Servlet类。
2°.利用反射机制的newInstance方法创建出一个Servlet的对象。
调用构造方法(创建ServletConfig对象) --> 调用init方法初始化(创建request和response对象) --> 调用Service方法(对response对象进行补充,由Tomcat解析返回浏览器)
3。如果服务器停止或者重新部署服务器。
调用destroy方法销毁对象。
(图片来源网络,侵权删)
注意事项:
1.servlet的自动加载:默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。
改变servlet创建对象的时机:提前到加载web应用。在配置文件加上 <load-on-startup>标签即可。
<servlet> <servlet-name>First</servlet-name> <servlet-class>com.yang.FirstServlet</servlet-class> <!-- 让servlet对象自动加载 --> <load-on-startup>1</load-on-startup> 注意: 整数值越大,创建优先级越低!! </servlet>
三、Servlet多线程问题
Servlet在Tomcat里面的运行机制:单实例,多线程
用户1和用户2都是调用了FirstServlet这个对象,但却由这个对象返回不一样的request和response对象。但还是会产生线程问题,比如用户1和用户2都用了FirstServlet的成员变量(共享变量)
1 例如:用户访客的例子 2 public class ThreadDemo extends HttpServlet{ 3 int count=1; 4 public void doGet(HttpServletRequest req,HttpServletReponse resp){ 5 resp.getWriter().write("你是第"+i+"个访客"); 6 count++; 7 } 8 } 9 如果这时候用户1访问该对象到第5行,还未执行第6行,这时候用户2进来了,那么就会造成用户1和用户2都返回"你是第1个访客"的结果,明显不符合逻辑。
因此应当修改为:
public class ThreadDemo extends HttpServlet{ int count=1; public void doGet(HttpServletRequest req,HttpServletResponse resp){ synchronized(TheadDemo.class){ //最好使用字节码类对象 resp.getWriter().write("你是第"+i+"个访客") count++; } } }