学习目标
- 掌握 servlet 实现原理
- 掌握 servlet 生命周期
- 掌握 servlet 监听器的使用
Servlet概论
Servlet 是什么?
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
–servlet
使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Servlet 架构
下图显示了 Servlet 在 Web 应用程序中的位置。
Servlet 任务
Servlet 执行以下主要任务:
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
Servlet 包
Java Servlet 是运行在带有支持 Java Servlet 规范的解释器的 web 服务器上的 Java 类。
Servlet 可以使用 javax.servlet 和 javax.servlet.http 包创建,它是 Java 企业版的标准组成部分,Java 企业版是支持大型开发项目的 Java 类库的扩展版本。
Servlet与Tomcat版本
Servlet基础
创建动态web工程:
说明:
dynamic web module指servlet的版本,servlet被包含在tomcat中。
- dynamic web module 2.4 对应Tomcat 5.5
- dynamic web module 2.5 对应Tomcat 6.0
- dynamic web module 3.0 对应Tomcat 7.0
- dynamic web module 3.1 对应Tomcat 7.0或者更高
- dynamic web module 4 对应Tomcat 8.0或者更高
一直next直到如下:
web.xml配置servlet
注解配置Servlet
在servlet3.0以后,我们可以不用再web.xml里面配置servlet,只需要加上@WebServlet注解就可以修改该servlet的属性了。
下面是@WebServlet的属性列表。
属性名 | 类型 | 描述 |
---|---|---|
name | String | 指定Servlet 的 name 属性,等价于 。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 |
value | String[] | 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于 标签。 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 标签。 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于 标签。 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于 标签。 |
description | String | 该 Servlet 的描述信息,等价于 标签。 |
displayName | String | 该 Servlet 的显示名,通常配合工具使用,等价于 标签。 |
从上表可见,web.xml可以配置的servlet属性,在@WebServlet中都可以配置。
如:
@WebServlet(description="描述", urlPatterns={ "/aaa"}, loadOnStartup=1)
public class indexServlet extends HttpServlet{}
Servlet 生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。
- Servlet 通过调用 init () 方法进行初始化。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 通过调用 destroy() 方法终止(结束)。
- Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
init()方法
init 方法被设计成只调用一次。
它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。
因此,它是用于一次性初始化。
Servlet 创建于用户第一次方位该Servlet的URL 时,但是也可以指定 Servlet 在服务器第一次启动时被加载。
每一个用户请求都会创建一个 Servlet 实例,并且产生一个新的线程。
init() 方法简单地创建或加载一些数据,这些数据将作用于 Servlet 的整个生命周期。
service()方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
destroy()方法
destroy() 方法只会在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
Servlet执行过程
- 同一个servlet是单例多线程的,只存在一个servlet对象,由多个线程异步执行该对象的方法。因此servlet的类属性是“线程不安全的”,对象属性是线程安全的,因为每个线程都会拷贝一份对象属性。
- Servelet容器维护了一个线程(等待执行代码的一组线程【Worker Thread】)池来处理各种请求。
- Servlet容器使用一个调度线程【Dispatcher Thread】来管理【Worker Thread】。
- 当tomcat启动时,按照在web.xml文件
<servlet>
元素中配置的<load-on-startup>序号</load-on-startup>
的顺序,容器会自动创建每个不同的Servlet对象,并执行。 - 当接受到第一个请求时,容器创建非Servlet
<load-on-startup>
的servlet对象,并执行。 - 执行过程按照Servlet生命周期执行
Servlet体系结构
ServletRequest接口
ServletRequest` -> `HttpServletRequest
相关方法
方 法 | 说 明 |
---|---|
getAttributeNames() | 返回当前请求的所有属性的名字集合 |
getAttribute(String name) | 返回name指定的属性值 |
getCookies() | 返回客户端发送的Cookie |
getsession() | 返回和客户端相关的session,如果没有给客户端分配session,则返回null |
getsession(boolean create) | 返回和客户端相关的session,如果没有给客户端分配session,则创建一个session并返回 |
getParameter(String name) | 获取请求中的参数,该参数是由name指定的 |
getParameterValues(String name) | 返回请求中的参数值,该参数值是由name指定的 |
getCharacterEncoding() | 返回请求的字符编码方式 |
getContentLength() | 返回请求体的有效长度 |
getInputStream() | 获取请求的输入流中的数据 |
getMethod() | 获取发送请求的方式,如get、post |
getParameterNames() | 获取请求中所有参数的名字 |
getProtocol() | 获取请求所使用的协议名称 |
getReader() | 获取请求体的数据流 |
getRemoteAddr() | 获取客户端的IP地址 |
getRemoteHost() | 获取客户端的名字 |
getServerName() | 返回接受请求的服务器的名字 |
getServerPath() | 获取请求的文件的路径 |
获得客户端信息
getRequestURL
方法返回客户端发出请求时的完整URL
。getRequestURI
方法返回请求行中的资源名部分。getQueryString
方法返回请求行中的参数部分。getPathInfo
方法返回请求URL
中的额外路径信息。额外路径信息是请求URL
中的位于Servlet
的路径之后和查询参数之前的内容,它以/
开头。getRemoteAddr
方法返回发出请求的客户机的IP
地址。getRemoteHost
方法返回发出请求的客户机的完整主机名。getRemotePort
方法返回客户机所使用的网络端口号。getLocalAddr
方法返回WEB
服务器的IP
地址。getLocalName
方法返回WEB
服务器的主机名。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z3HlqTJc-1641215496469)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211230155915260.png)]
获得客户端请求参数
获取(客户端提交的数据)
getParameter(String)
方法(常用)-获取单个字段getParameterValues(String name)
方法(常用)-获取多选字段getParameterMap()
方法(编写框架时常用)- 将所有字段全部封装成map
getParameterNames()
方法(不常用)
案例:获取请求头
package com.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServletTestRequest2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("UTF-8"