文章目录
- 基本介绍
- 入门步骤
- 执行原理
- Servlet 生命周期
- 线程安全问题
- 解决方式
- Servlet 注解配置
- Servlet 继承与实现体系
基本介绍
servlet,server applet,服务器端小程序
servlet 是一个接口,定义了 Java 类被浏览器访问(tomcat 识别)的规则。
我们需要自己定义一个类,实现 Servlet 接口。
入门步骤
1.创建 JavaEE 项目
2.定义一个类,实现 Servlet 接口或者继承自 GenericServlet 或者 HttpServlet
public class ServletDemo01 implements Servlet # 实现多个方法
public class ServletDemo01 extends GenericServlet # 实现service方法
public class ServletDemo01 extends HttpServlet # 覆盖重写doGet和doPost方法
3.实现接口中的抽象方法
4.配置 Servlet
在 web.xml 文件中配置如下:
<servlet><servlet-name>demo01</servlet-name><servlet-class>priv.lwx.javaex.web.servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping><servlet-name>demo01</servlet-name><url-pattern>/demo01</url-pattern>
</servlet-mapping>
执行原理
1.当服务器 tomcat 接受到客户端浏览器的请求后,会解析请求 URL 路径,获取访问的 Servlet 的资源路径
2.解析 web.xml
文件,查找是否有对应的 <url-pattern>
3.如果有,则找到对应的 <servlet-class>
标签,从而找到 Servlet 的全类名
4.tomcat 会将 Servlet 类的字节码文件加载进内存,再通过反射机制创建 Servlet 类的实例对象
5.最后会调用有关的方法
Servlet 生命周期
1.Servlet 被创建:执行 init 方法,只执行一次
在 web.xml
文件中的 <servlet>
标签下通过 <load-on-startup>
标签配置自然数值可以在服务器启动时创建 Servlet 实例,值越小优先级越高,服务器会按从小到大的顺序创建 Servlet 实例。负数则表示第一次访问 Servlet 时创建实例,默认值是 -1
。
Servlet 的 init 方法,只执行一次,说明一个 Servlet 在内存中只存在一个对象, Servlet 是单例的。
多个用户同时访问时,可能存在线程安全问题。
2.提供服务:执行 service 方法,每次访问都会执行一次
3.被销毁:执行 destroy 方法,tomcat 正常关闭时执行一次。
服务器关闭时 Servlet 被销毁,在销毁 Servlet 前会执行一次 destroy 方法,用于释放资源。
线程安全问题
Servlet 线程安全问题产生的原因:
在默认情况下,容器只会为每一个 Servlet 类创建唯一的一个实例,当有多个请求到达容器,就有可能有多个线程同时访问同一个实例。
解决方式
1.加锁(可以对整个 service 方法加锁或者对代码块加锁,建议使用代码块加锁)
2.让 Servlet 实现 SingleThreadModle 接口(不建议使用)
SingleThreadModel 接口是一个标识接口(没有定义任何的方法)。容器会为实现该接口的 Servlet 创建多个实例,即一个线程分配一个。这种方式创建了过多的 Servlet 实例,系统开销太多,不建议使用
3.尽量不要在 Servlet 中定义成员变量。如果一定要定义成员变量,则尽量设置成可读的,不要去修改
Servlet 注解配置
Servlet 3.0 及以上版本支持注解配置,可以不需要 web.xml。
步骤:
1.创建 Java EE 项目,选择 Servlet 的版本 3.0 及以上,可以不创建 web.xml
2.定义一个实现 Servlet 接口的类
3.实现抽象方法
4.在类上使用 @WebServlet
注解进行配置
@WebServlet(urlPatterns = "资源路径")
@WebServlet(value = "资源路径")
@WebServlet("资源路径")
以上三种方式都行,推荐最后一种方式。
资源路径的格式:
1./xxx
2./xxx/xxx
3.*.do
@WebServlet("*.do")
Servlet 继承与实现体系
HttpServlet 类对 http 协议进行了封装,简化操作。
自定义 Servlet 类时,通常是去继承抽象类 HttpServlet,重写 doGet 和 doPost 方法。