---------------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

public
void init() throws ServletException {

System.out.println("===== init without parameters =====");

super.init();

}

 
 

@Override

public
void init(ServletConfig config) throws ServletException {

System.out.println("===== init with parameters =====");

super.init(config);

}

 
 

@Override

protected
void 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

public
void destroy() {

System.out.println("===== destroy =====");

super.destroy();

}

 
 

 
 

}

 
 

 
 

在部署描述符 web.xml 中注册 servlet:

 
 

<?xml
version="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/javaee http://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处理流程分析的更多相关文章

  1. Servlet处理流程分析-Servlet学习之旅(二)

    tomcat的处理处理客户端流程分析 tomcat即是servlet容器也具有web服务器的功能,即也具有html页面的功能. 1.首先客户端会将html请求发给tomcat内置的web服务器 2.w ...

  2. Servlet执行流程和生命周期【慕课网搬】

    Servlet执行流程(GET方式为例) 首先用户客户端浏览器发出Get方式(点击超链接方式)向浏览器发出请求. 服务器接收到客户端点击超链接,接收到GET请求之后,服务器到WEB.xml中<s ...

  3. Solr4.8.0源码分析(5)之查询流程分析总述

    Solr4.8.0源码分析(5)之查询流程分析总述 前面已经写到,solr查询是通过http发送命令,solr servlet接受并进行处理.所以solr的查询流程从SolrDispatchsFilt ...

  4. SpringMVC的流程分析(一)—— 整体流程概括

    SpringMVC的整体概括 之前也写过springmvc的流程分析,只是当时理解的还不透彻所以那篇文章就放弃了,现在比之前好了些,想着写下来分享下,也能增强记忆,也希望可以帮助到人,如果文章中有什么 ...

  5. Struts2的工作流程分析

    Struts2的工作流程分析 Posted on 2011-02-22 09:32 概述 本章讲述Struts2的工作原理. 读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验, ...

  6. SpringBoot启动流程分析(一):SpringApplication类初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  7. SpringBoot启动流程分析(二):SpringApplication的run方法

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  8. 011-Spring Boot 运行流程分析SpringApplication.run

    一.程序入口 1.1.静态方法 //直接调用run方法 ConfigurableApplicationContext context = SpringApplication.run(App.class ...

  9. Spring MVC启动流程分析

    本文是Spring MVC系列博客的第一篇,后续会汇总成贴子. Spring MVC是Spring系列框架中使用频率最高的部分.不管是Spring Boot还是传统的Spring项目,只要是Web项目 ...

随机推荐

  1. Java编程思想(第4版) 中文清晰PDF完整版

    Java编程思想(第4版) 中文清晰PDF完整版 [日期:2014-08-11] 来源:Linux社区  作者:Linux [字体:大 中 小]     <Java编程思想>这本书赢得了全 ...

  2. keep-alive使用笔记

    vue2.0提供了keep-alive组件,用来缓存组件,避免多次加载,减少性能消耗. 1.将整个网页缓存起来 <router-view class="view" keep- ...

  3. Spring Cloud之Zuul负载均衡

    Zuul网关默认是实现负载均衡的,不需要任何配置.默认开启ribbon效果的 可以启启动两个服务端口,访问下.

  4. Struts2 内核之我见

    Struts2 内核之我见 完整分析 Struts2 内核中文文档 本文首先探讨了 Struts2 核心控制器的源码,以帮助解读 Struts2 的工作流程.接着讲解相关外围类.最后对 Struts ...

  5. SetOperations

    无序集合,add的顺序不是存储顺序 1.add(K key, V value) 2.difference(K key, otherK[s]) :差集,返回Set 3.differenceAndStor ...

  6. Java企业微信开发_03_自定义菜单

    一.本节要点 1.菜单相关实体类的封装 参考官方文档中的请求包的内容,对菜单相关实体类进行封装. 这里需要格外注意的是,企业微信中请求包的数据是Json字符串格式的,而不是xml格式.关于json序列 ...

  7. struts2--Basic(一)

    Struts是流行和成熟的基于MVC设计模式的WEB应用程序框架. 帮助我们减少在运用MVC设计模式来开发Web应用的时间. 1.下载添加jar包 2. 准备配置文件 web.xml <filt ...

  8. alt+shift+j 自动添加类的文档注释 Myeclipse

    alt+shift+j  自动添加类的文档注释 Myeclipse ctrl+shift+y 将选中的内容大写换成小写 +x是转换成大写

  9. 解编码框架的比较(protobuf,thrift,Marshalling,xml)

    1.ProtoBuf 特点: 1.结构化数据存储格式 2.高效的解编码性能. 3.语言无关,平台无关,扩展性好. 4.官方支持java,c++,python三种语言. 5.性能比较好 (与之对比xml ...

  10. luogu2627 修剪草坪

    dp[i]表示1~i最大效率 记一下前缀和 转移就是f[i]=max(f[i],f[j-1]-sum[j])+sum[i] (i-k<=j<=i) 发现括号里的只与j有关 开一个单调队列维 ...