Servlet
是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
Servlet带给我们最大的作用就是能够处理浏览器带来HTTP请求,并返回一个响应给浏览器,从而实现浏览器和服务器的交互。
Servlet的工作模式
- 客户端发送请求至web服务器
- web服务器收到客户端的Servlet访问请求后:
- web服务器检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
- 装载并创建该Servlet的一个实例对象。
- 调用Servlet实例对象的init()方法。
- 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
- WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
- 服务器将响应返回客户端
Servlet的生命周期
- 加载Servlet。当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
- 初始化。当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
- 处理服务。当浏览器访问Servlet的时候,Servlet 会调用service()方法处理请求
- 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
- 卸载。当Servlet调用完destroy()方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作。
- 简单总结:只要访问Servlet,service()就会被调用。init()只有第一次访问Servlet的时候才会被调用。destroy()只有在Tomcat关闭的时候才会被调用。
Servlet的特点
映射关系
一个已经注册的Servlet可以被多次映射同一个Servlet可以被映射到多个URL上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<!--
当浏览器访问http://localhost:8080/Demo1时:
1、发现Tomcat中的web.xml有配置这个映射路径 <url-pattern>/Demo1</url-pattern>
2、查看映射路径的名字 <servlet-name>Demo1</servlet-name>
3、通过映射路径的名字找到配置servlet的名字 <servlet-name>Demo1</servlet-name>
4、通过servlet名找到servlet编译后class文件存放的位置
5、执行MyServlet <servlet-class>
-->
<servlet>
<!--为Demo1配一个名字,一般都会和类名一致-->
<servlet-name>Demo1</servlet-name>
<!--类的存放位置在哪里【有包名的话需要添加上包名】-->
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
</servlet>
<!--为Demo1配置映射路径-->
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<!--外界访问Demo1的路径-->
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/ouzicheng</url-pattern>
</servlet-mapping>
无论我访问的是http://localhost:8080/Demo1还是http://localhost:8080/ouzicheng。我访问的都是Demo1。Servlet映射的URL可以使用通配符
在servlet3.0以后,web.xml中对Servlet配置,同样可以在@WebServlet注解中配置.
下面是@WebServlet的属性列表:属性名 类型 描述 name String 指定Servlet 的 name 属性,等价于 <servlet-name>
。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。value String[] 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式。等价于 <url-pattern>
标签。loadOnStartup int 指定 Servlet 的加载顺序,等价于 <load-on-startup>
标签。initParams WebInitParam[] 指定一组 Servlet 初始化参数,等价于 <init-param>
标签。asyncSupported boolean 声明 Servlet 是否支持异步操作模式,等价于 <async-supported>
标签。description String 该 Servlet 的描述信息,等价于 <description>
标签。displayName String 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name>
标签。
Servlet————单例模式
- 浏览器多次对Servlet的请求,一般情况下,服务器只创建一个Servlet对象,也就是说,Servlet对象一旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。
- 在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。
- 对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
通配符
通配符有两种格式:
- *.扩展名
- 正斜杠(/)开头并以“/*”结尾。
*.
扩展名的优先级最低
线程安全问题
当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程。当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题。
原则:
- 如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制synchronized (对象){}
- 如果一个变量不需要共享,则直接在 doGet() 或者 doPost()定义.这样不会存在线程安全问题
web资源的访问都需要访问Servlet
缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
web站点信息配置
- web.xml文件支持对整个站点进行配置参数信息【所有Servlet都可以取到该参数信息】
1 | <context-param> |
web工程中URL地址的写法
如果”/“是给服务器用的,则代表当前的web工程,如果”/“是给浏览器用的,则代表webapps目录。
ServletConfig对象
此对象可以读取web.xml中配置的初始化参数。
————当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。
参数信息放置在web.xml中可以方便修改。
ServletContext对象
当Tomcat启动的时候,就会创建一个ServletContext对象。它代表着当前web站点
- 所有Servlet都共享着一个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯。
- ServletConfig获取的是配置的是单个Servlet的参数信息,ServletContext可以获取的是配置整个web站点的参数信息
- 利用ServletContext读取web站点的资源文件
- 实现Servlet的转发【用ServletContext转发不多,主要用request转发】
应用
多个Servlet通过ServletContext对象实现数据共享
1 | //ServletContextDemo1: |
获取WEB应用的初始化参数
1 |
|
1 | public class ServletContextDemo3 extends HttpServlet { |
用servletContext实现请求转发
1 | //ServletContextDemo4: |
利用ServletContext对象读取资源文件
1 | /** |
在客户端缓存Servlet的输出
1 | public class ServletDemo5 extends HttpServlet { |