Servlet处理流程分析
来源:互联网 发布:下载哈萨克dombira软件 编辑:程序博客网 时间:2024/06/06 18:01
---------------siwuxie095
Tomcat 处理客户端请求的方式:
Tomcat 既是一个 Servlet 容器,又具有 Web 服务器的功能,
也即 拥有处理静态 HTML 页面的能力
只不过相对于Apache、Nginx 等专业的 Web 服务器而言,
其功能又弱一些
客户端从发起请求,到接收响应的处理流程:
(1)客户端发送HTTP 请求,该请求会首先到达 Tomcat 内置的 Web 服务器
(2)Tomcat 内置的 Web 服务器接收到请求后,将请求转发给 Servlet 容器
(3)Servlet 容器接收到请求后,加载 Servlet,产生 Servlet 实例后,会向其
传递表示请求和响应的对象,然后Servlet 实例使用 请求对象,得到客户端的
请求信息,并进行响应处理
「请求和响应对象,即HttpServletRequest 对象 和 HttpServletResponse 对象」
(4)该Servlet 处理完毕之后,有可能会将请求转发给其他的 Servlet 继续进行处理
(5)全部处理完毕后,处理结果通过响应对象,发送回客户端。
至此,一个客户端请求处理完毕
Servlet 的执行流程:
(1)当Servlet 被装载并实例化后,Servlet 容器会首先调用 init() 方法
对 Servlet 进行初始化,只有在init() 方法调用成功后,Servlet 才能处于
服务状态,接收客户端的请求并进行处理
init() 方法在Servlet 的生命周期中只会被调用一次
(2)当Servlet 执行完初始化操作,就会调用service() 方法来对客户端
的请求进行处理
service() 方法在Servlet 的生命周期中会被调用多次,这和请求次数有关
(3)当Servlet 不再使用,Servlet 容器销毁 Servlet 实例之前,
会调用 destroy() 方法
destroy() 方法在 Servlet 的生命周期中也只会被调用一次
工程结构目录如下:
HelloServlet.java:
package com.siwuxie095.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//HelloServlet继承自 HttpServlet
public class HelloServlet extends HttpServlet {
/**
*先覆盖父类 HttpServlet的方法:
*右键->Source->Override/Implement methods
*选择 HttpServlet的 service()和 GenericServlet的 init()和 destroy()
*
*这样,HelloServlet的骨架生成完毕
*/
@Override
publicvoid init() throws ServletException {
System.out.println("===== init without parameters =====");
super.init();
}
@Override
publicvoid init(ServletConfig config) throws ServletException {
System.out.println("===== init with parameters =====");
super.init(config);
}
@Override
protectedvoid service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("===== service =====");
//通过 HttpServletResponse 获取一个 PrintWriter对象
//PrintWriter是一个以字符为单位的输出流
PrintWriter pw=resp.getWriter();
pw.println("Hello World");
//输出完毕,关闭流
pw.close();
}
@Override
publicvoid destroy() {
System.out.println("===== destroy =====");
super.destroy();
}
}
在部署描述符 web.xml 中注册 servlet:
<?xmlversion="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1">
<display-name>HelloServlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--添加一个 servlet元素,它有两个子元素 -->
<!-- servlet元素用于注册 servlet -->
<!-- servlet-name用于设置 servlet的注册名称(可随意设置) -->
<!-- servlet-name用于设置 servlet的完全限定名 -->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.siwuxie095.servlet.HelloServlet</servlet-class>
</servlet>
<!--添加一个 servlet-mapping元素,它有两个子元素 -->
<!-- servlet-mapping元素用于映射 servlet对外访问的路径 -->
<!-- servlet-name也是指 servlet的注册名称,需保持一致 -->
<!-- servlet-name是 servlet和 servlet-mapping联系起来的唯一标志 -->
<!-- url-pattern用于指定 servlet对外访问的路径 -->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/Hello</url-pattern>
</servlet-mapping>
</web-app>
部署描述符web.xml 在 WEB-INF 目录下,如果没有,手动创建即可
选择工程 HelloServlet,右键->Java EE Tools->Generate Deployment Descriptor Stub
注意:
init() 方法有两个:没有参数的 和 有参数的
推荐重写无参的 init() 方法,因为重写无参的init() 方法,
无需手动调用 super.init() 方法,即 可以删除 或 注释掉
如果重写有参的init() 方法,则必须手动调用 super.init() 方法
重写init() 方法并不是必须的,如果要在 Servlet 实例化时,执行
一些初始化操作,才重写init() 方法
选择Tomcat,右键->Add and Remove,把 HelloServlet 添加到 Tomcat 中
启动Tomcat,控制台只有 Tomcat 的启动日志,而 HelloServlet 的方法体中
的日志信息并没有打印出来,说明在没有访问之前,Servlet 是没有实例化的
在浏览器中输入:localhost:8080/HelloServlet/Hello进行访问,控制台输出:
通过日志信息可以看出:
先执行有参的init() 方法,再执行无参的 init() 方法,最后执行service() 方法
有参的init() 方法的父类实现:
无参的init() 方法的父类实现:
有参的init() 方法的父类实现中显式的调用了无参的 init() 方法,这是
两个 init() 方法的日志信息都被打印出来的原因
此时,关闭Tomcat,destroy() 方法的日志信息并没有打印,
说明 destroy() 方法没有调用
「当Servlet 容器销毁 Servlet 实例时,才会调用 destroy() 方法」
Servlet 容器销毁 Servlet 实例的过程:
将HelloServlet 导出到 Tomcat 安装目录的 webapps 目录下
在CMD 窗口中输入 startup 或 startup.bat,启动 Tomcat 并监视日志输出
在浏览器输入:localhost:8080/HelloServlet/Hello进行访问,开始输出日志:
打开Tomcat 的应用管理界面:localhost:8080/manager/html,找到 HelloServlet
点击Undeploy,destroy() 方法就会被调用
日志中输出了destroy() 方法中的日志
在destroy() 方法中可以执行资源释放、日志记录的操作,
这是 destroy() 方法的最大作用
【made by siwuxie095】
- Servlet处理流程分析
- Servlet处理流程分析
- Servlet处理流程分析-Servlet学习之旅(二)
- Servlet处理的流程
- Servlet处理的流程
- Servlet处理的基本流程
- servlet处理的基本流程
- compact处理流程分析
- 中断处理流程分析
- django处理流程分析
- Struts2处理流程分析
- 中断处理流程分析
- Servlet学习笔记_04_servlet处理流程
- servlet代码分析-整个执行流程
- servlet代码分析-整个执行流程
- android TouchEvent处理流程分析
- WebRTC视频分析:处理流程
- UserScan的处理流程分析
- Linux的task_struct中的成员及代表意义
- mysql创建视图,存储过程,事件
- thrift总结
- 监听系统广播Action
- 深入浅出RPC
- Servlet处理流程分析
- 错误1error C2143: 语法错误 : 缺少“;”(在“&”的前面)
- Android 编程下 Activity 的创建和应用退出时的销毁
- 常用数据库分页查询语句
- 获取id 的一种策略
- 手机版倒计时问题 + 伪异步
- Struts2中访问web元素
- Tips:shell 里传递多行内容到文本 及sudo 配置
- 【转】Android 常用adb shell 命令