深入理解Servlet
来源:互联网 发布:sql增删改查面试题 编辑:程序博客网 时间:2024/06/05 04:31
一、Web服务器
从事web开发的人,会很清楚一个东西叫 Web服务器,比如J2EE开发—Tomcat,Jetty,.NET开发—IIS等。HTTP服务器是使用 HTTP(超文本传输协议) 与客户机浏览器进行信息交流。下面就是HTTP服务器简单交互图:(来自[JavaEE 要懂的小事] Http相关 博客)
HTTP服务器是Web服务器的一种,也是开发最常见的,自然还有其他方式进行信息交互,比如FTP文件服务器…
Web服务器是可以向发出请求的浏览器提供文档的程序。其核心过程为连接过程 — 请求过程 — 应答过程 — 关闭连接
这让我想到了Tomcat架构的一张图:
二、Tomcat 简单说几句
如图,Tomcat 包含了核心服务模块:Connector连接模块 和 Container 容器。Tomcat Server 核心是一个 Servlet/JSP Container。对每一个HTTP请求,过程如下
— 获取连接— Servlet来分析请求(HttpServletRequest)— 调用其service方法,进行业务处理— 产生相应的响应(HttpServletResponse)— 关闭连接
如图:
蓝色线指向过程是请求,绿色线指向过程是响应过程。也就是上面Web服务器核心过程:“连接过程 — 请求过程 — 应答过程 — 关闭连接”
三、我第一个Servlet
什么是Servlet?(每次都会不停的问自己,这是什么“What”?紧接着应该是什么用“How”吧)
在 JavaEE 6文档中,介绍如下
“Servlet 是运行在Web服务器的Java小程序。Servlet可以获取并针对Web客户端的请求作出响应。一般情况下,通过HTTP,即超文本传输协议,进行传输通信。”A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
所以,Servlet 是Web服务器核心工作的抽象。它不单单只是实现HttpServlet,可能实现有FtpServlet(这个我猜的)等。相对较多的Web开发,知道的肯定是HttpServlet。
补充,在Servlet规范是这样写道的:
Serlvet是基于Java技术的Web组件,容器托管的,用于生产动态内容。它也是基于平台无关的Java类格式,被编译为平台无关的字节码,可以被基于Java技术的web server动态加载并运行。这里容器,有时候也称为servlet 引擎。
在 JavaEE 6文档中,是这样介绍HttpServlet:
“HttpServlet 提供了一个能被继承后创建一个适应Web网站的Http Servlet的抽象类。”Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site.
光说不练假把式,练一个“Hello,Servlet/JSP World!”:
/* * Copyright [2015] [Jeff Lee] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//** * @author Jeff Lee * @since 2015-6-25 19:46:45 * HelloWrold案例 */@WebServlet(urlPatterns = "/helloWorld.html")public class HelloWorldServletT extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ // 获取输出打印对象 PrintWriter out = resp.getWriter(); out.println("Hello,Servlet/JSP World!"); }}
三、分析源码
@WebServlet(urlPatterns = "/helloWorld.html")
@WebServlet 注解用于声明一个HttpServlet的配置。其中,urlPatters = “/helloWorld.html”,urlPatterns复数形式,说明至少一个URL必须被申明。它和另一个value必须存在一个,但不能同时存在。如果要匹配多个URL路径的话,如下:
@WebServlet(urlPatterns = { "/helloWorld01.html", "/helloWorld02.html" }
下面有个@Override,重写了父类HttpServlet的doGet方法。我们先看看父类HttpServlet。HttpServlet是一个抽象类,它提供了以下方法:
— doGet , 服务于 HTPP GET 请求— doPost , 服务于 HTTP POST 请求— doPut , 服务于 HTTP PUT 请求— doDelete,服务于 HTTP DELETE 请求
如图:
对于不同的请求,HttpServlet的子类必须相应的实现至少一个方法,通常来说,会是其中一个,这样代码比较清晰。那父类的doGet方法做了什么工作呢?
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } }
这里就简单的获取了下HTTP协议及Http Local信息,然后可以协议是否是1.1,做出分别是405或者400HTTP状态码的响应。
回到HelloWorldServletT.java 这里:
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取输出打印对象 PrintWriter out = resp.getWriter(); out.println("Hello,Servlet/JSP World!");}
表示该HelloWorldServletT会接受Http GET请求,并OOM到HttpServletRequest,并执行里面的逻辑代码和返回响应。 这里从HttpServletResponse对象中获取到输出打印对象PrintWriter,然后输出了“Hello,Servlet/JSP World!”。
完毕!哦还有一点补充补充补充:
print,这里还好一句话。如果打印个table会很麻烦,因此有一个JSP的东西出现了,是Servlet的HTML化身。
五、深入Servlet 具体过程
又回到这个简单的 Get Servlet代码:
public class HelloWorldServletT extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ // 获取输出打印对象 PrintWriter out = resp.getWriter(); out.println("Hello,Servlet/JSP World!"); }}
这过程总结如下:
— 从浏览器(Client)获取连接”/helloWorld.html”— Tomcat Connector模块将请求(Request)传递给 Container模块— Container 模块会做以下事情— 分析HTPP请求信息,组装成HttpServletRequest对象— 创建新的HttpServletResponse对象— 根据路由配置,搜索相应的Servlet,并创建一个线程用于处理本次请求。此时线程会将上面Request和Response对象的索引,传递给Servlet— 新线程中的Servlet处理逻辑— 线程结束后,通过HttpServletResponse对象的PrintWriter,返回浏览器一个信息
过程图如下:
蓝色线指向过程是请求,绿色线指向过程是响应过程,橙色线指向过程是内部处理过程。
有些面试题会这样问:
Servlet是线程安全的吗?不是,一个servlet实现类只会有一个实例对象,多个线程是可能会访问同一个servlet实例对象的,线程安全问题都是由全局变量及静态变量引起的。
因此,Servlet对象实例化是在以第一次请求此Servlet时,如果访问后,实例对象存在内存中,只会在服务器停止时,它才会消失。它不会随着各个线程结束而结束。因此下次访问Servlet时,Servlet Container会搜索相应的Servlet,如果不存在,Container新建相应的Servlet。这也是我们想要的结果。
再来个恶心的面试题:
Servlet是单例吗?不一定是,在一个ServeltName情况下是的。在多个ServletName匹配到一个Servlet类时,该Servlet不是单例。网上答案:在web.xml中声明了几次,即使同一个Servlet,如果声明多次,也会生成多个实例。
- 深入理解Servlet
- 深入理解Servlet [转]
- servlet生命周期深入理解
- servlet深入理解
- 深入理解Servlet原理
- 深入理解Servlet
- servlet生命周期深入理解
- 深入理解Servlet线程安全问题
- 深入理解Servlet线程安全问题
- Servlet源码理解。深入分析。
- Servlet、Filter、Listener深入理解
- Servlet、Filter、Listener深入理解
- Servlet、Filter、Listener深入理解
- Servlet、Filter、Listener深入理解
- 深入理解Servlet线程安全问题
- 深入理解Servlet线程安全问题
- 深入理解Servlet线程安全性问题
- 深入理解Servlet转发和重定向
- TP事物-不可缺少的操作
- MySQL存储过程和函数详细定义
- mysql数据库字符处理函数
- php-使用哈希对象缓存
- mysql数据库转sqlite.db数据库
- 深入理解Servlet
- 手把手教你使用Systrace(一)
- JavaScript学习笔记_尾调用优化
- 关于微信公众号支付获取用户openId的方法
- LevelDB使用指南
- 零基础学图形学(11) 几何知识——球坐标和三角函数
- Java面向对象习题
- 【bzoj3012】[Usaco2012 Dec]First!
- 关于经常遇到的tomcat内存溢出问题