sun 公司制订的一种基于 Java 技术的 WEB 服务器功能的组件规范。1997 年六月,Servlet 1.0 版本发行,最新版本 Servlet 4.0 处于研发状态。
所谓的 Servlet 容器,有时候也称作为 Servlet 引擎,作为 Web 服务器或应用服务器的一部分。通过请求和响应对话,提供 Web 客户端与 Servlets 交互的能力。容器管理 Servlets 实例以及它们的生命周期。
一、Servlet 组件
Servlet 容器的组件大致可以分为以下几类:
Servlet 组件
├── 服务组件
| ├── javax.servlet.Servlet
| └── javax.servlet.Filter(since Servlet 2.3)
|
├── 上下文组件
| ├── javax.servlet.ServletContext
| ├── javax.servlet.http.HttpSession
| ├── javax.servlet.http.HttpServletRequest
| ├── javax.servlet.http.HttpServletResponse
| └── javax.servlet.http.Cookie(客户端)
|
├── 配置
| ├── javax.servlet.ServletConfig
| └── javax.servlet.FilterConfig(since Servlet 2.3 )
|
├── 输入输出
| ├── javax.servlet.ServletInputStream
| └── javax.servlet.ServletOutputStream
|
├── 异常
| └── javax.servlet.ServletException
|
├── 事件(since Servlet 2.3 )
| ├── 生命周期类型
| | ├── javax.servlet.ServletContextEvent
| | ├── javax.servlet.http.HttpSessionEvent
| | └── java.servlet.ServletRequestEvent
| ├── 属性上下文类型
| | ├── javax.servlet.ServletContextAttributeEvent
| | ├── javax.servlet.http.HttpSessionBindingEvent
| | └── javax.servlet.ServletRequestAttributeEvent
| |
├── 监听器(since Servlet 2.3)
| ├── 生命周期类型
| | ├── javax.servlet.ServletContextListener
| | ├── javax.servlet.http.HttpSessionListener
| | ├── javax.servlet.http.HttpSessionActivationListener
| | └── javax.servlet.ServletRequestListener
| |
└────└── 属性上下文类型
├── javax.servlet.ServletContextAttributeListener
├── javax.servlet.http.HttpSessionAttributeListener
├── javax.servlet.http.HttpSessionBindingListener
└── javax.servlet.ServletRequestAttributeListener
-
Servlet 接口:init(ServletConfig config)、service(ServletRequest req, ServletResponse res)、destroy() -
GenericServlet 抽象类:实现了 Servlet 接口中的 init, destroy 方法 -
HttpServlet 抽象类:继承了 GenericServlet 抽象类,实现了 service() -
ServletConfig 接口:String getInitParameter(String paraName) -
ServletRequest 接口:HttpServletRequest 的父接口 -
ServletResponse 接口:HttpServletResponse 的父接口
一、Servlet
1.1 Servlet 的生命周期
Servlet 的生命周期指 Servlet 容器如何去创建 Servlet 对象、如何调用 Servlet 对象的方法来处理请求、以及如何销毁 Servlet 对象的整个过程。
Servlet 生命周期的三个阶段:
(1) 初始化
当容器启动或者第一次执行时,Servlet#init(ServletConfig) 方法被执行,初始化当前 Servlet 。
(2) 处理请求
当 HTTP 请求到达容器时,Servlet#service(ServletRequest, ServletResponse) 方法被执行,来处理请求。
(3) 销毁
当容器关闭时,容器将会调用 Servlet#destroy() 方法被执行,销毁当前 Servlet。
1.2 Servlet 如何处理请求资源路径
-
Servlet 容器会先假设访问的是一个 Servlet ,会依据应用名(appname)找到应用所在的文件夹,然后找到 web.xml 文件。
-
匹配
- 精确匹配(完全匹配)
- 通配符匹配:使用 * 匹配任意长度的字符串。eg:
/* - 后缀匹配:使用 . 开头,后面可以接任意字符。eg:
.do
-
如果都不匹配,则容器认为访问的是一个静态资源文件(html/css/js),如果找到则返回,否则返回404。
1.3 Servlet 是如何运行的?
- 浏览器依据 ip, port 建立与 Servlet 容器之间的连接。
- 浏览器将请求数据打包(即按照 http 协议的要求,将相关数据封闭成一个数据包,即请求数据包)并发送给 Servlet 容器。
- Servlet 容器解析请求数据包,并将解析后的数据放到 request 对象上。同时创建一个 response 对象。
- Servlet 容器依据请求资源路径找到 Servlet 的配置,然后创建 Servlet 对象。
- Servlet 调用 service 方法,并且会将事先创建好的 request 对象和 response 对象作为 service 方法的参数传递给 Servlet 对象。
- Servlet 通过 request 对象获得请求参数,进行相应的处理,然后将处理结果写到 response 对象上。
- Servlet 读取 response 对象上的数据,然后将处理结果打包(响应数据包)并发送给浏览器。
- 浏览器解析响应数据包,将返回的数据展现给用户。
1.4 实例
public class HelloWorldServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
//1. 读请求参数值
String qtyStr = req.getParameter("qty");
int qty = Integer.parseInt(qtyStr);
//2. 处理请求
String rs = "";
for (int i = 0; i < qty; i++) {
rs += "<h1>Hello World</h1>";
}
//3. 设置一个消息头 content-type,告诉浏览器返回的数据类型是一个 html 文档及编码格式
//告诉服务器使用 out 输出时使用指定的编码格式进行编码
res.setContentType("text/html;charset=utf-8");
//4、获得一个输出流
PrintWriter out = res.getWriter();
//5、调用流的方法进行输出,其实质是将处理结果写到了 res 对象上
out.println(rs);
out.close();
}
}
配置 WEB-INF/web.xml 配制文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>helloWord</servlet-name>
<!--类名要完整(包名,类名都要全)-->
<servlet-class>com.herolei.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloWord</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
启动程序,访问 http://localhost:8080/hello?qty=30
补充:web 打包后的目录如下
appname(应用名)
└──WEB-INF
├──classes .class文件
├──lib .jar文件,lib文件夹可选
└──web.xml 部署描述文件
二、Listener
Servlet 规范当中定义的一种特殊的组件,用来监听容器产生的事件并进行处理。
容器会产生两大类事件:
- 生命周期相关的事件:容器在创建或者销毁 request, servletContext(Servlet 上下文)时产生的事件。对应的接口有 ServletRequestListener、ServletContextListener。
- 绑定相关的事件:容器调用了 request, servletContext 的 setAttribute, removeAttribute 时产生的事件。。对应的接口有 ServletContextAttributeListener、ServletRequestAttributeListener。
public interface ServletContextListener extends EventListener {
// 容器初始化
void contextInitialized(ServletContextEvent ctx);
// 容器销毁
void contextDestroyed(ServletContextEvent ctx);
}
public interface ServletContextAttributeListener extends EventListener {
void attributeAdded(ServletContextAttributeEvent event);
void attributeRemoved(ServletContextAttributeEvent event);
void attributeReplaced(ServletContextAttributeEvent event);
}
三、Filter
public interface Filter {
// 初始化 Filter
void init(FilterConfig filterConfig) throws ServletException;
// 调用,如果要继续调用下一个 Filter,需要调用 chain.doFilter(request, response)
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
// 销毁
public void destroy();
}
public interface FilterChain {
void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}
Filter 生命周期如下:
(1) 初始化
当容器启动时,Filter#init(FilterConfig) 方法被执行,初始化当前 Filter。
(2) 处理请求
当 HTTP 请求到达容器时,Filter#doFilter(ServletRequest,ServletResponse,FilterChain) 方法被执行,来拦截请求,在 Servlet#service(ServletRequest,ServletResponse) 方法调用前执行。
(3) 销毁
当容器关闭时,容器将会调用 Filter#destroy() 方法被执行,销毁当前 Filter。
参考:
每天用心记录一点点。内容也许不重要,但习惯很重要!