深入浅出 JavaWeb:Servlet必会必知
一、Web服务器
从事web开发的人,会很清楚一个东西叫HTTP服务器,比如JEE开发—Tomcat,Jetty,.NET开发—ISS等。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,即超文本传输协议,进行传输通信。”
1A 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。
在JavaEE 6文档中,是这样介绍HttpServlet:
“HttpServlet 提供了一个能被继承后创建一个适应Web网站的Http Servlet的抽象类。”
1Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site.
光说不练假把式,练一个“Hello,Servlet/JSP World!”:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/* * 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 * * * 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!"); }} |
右键该HelloWorldServletT.java文件 — Run As — Run On Server — 选择Tomcat服务器 — Finish即可
![]()
![]()
等待片刻,你可看到网页上如下输出。这就是客户端从HttpServlet获取到的响应:
![]()
休息一下吧~ 看看小广告:
开源代码都在我的gitHub上哦 — https://github.com/JeffLi1993
三、分析源码
|
1
|
@WebServlet(urlPatterns = "/helloWorld.html") |
@WebServlet 注解用于声明一个HttpServlet的配置。其中,urlPatters = “/helloWorld.html”,urlPatterns复数形式,说明至少一个URL必须被申明。它和另一个value必须存在一个,但不能同时存在。如果要匹配多个URL路径的话,如下:
|
1
|
@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方法做了什么工作呢?
|
1
2
3
4
5
6
7
8
9
10
11
|
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 这里:
|
1
2
3
4
5
6
7
|
@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代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
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。这也是我们想要的结果。
六、小结
发现这一博客写的太多,回头一看。可以写成三个文章了。言归正传本文要点如下
1、简单介绍Web服务器 及 Tomcat容器
2、第一个Sevlet的开发及使用
3、深入源码及api介绍使用
4、总结一次请求及响应的真实过程
深入浅出 JavaWeb:Servlet必会必知的更多相关文章
- 图解 & 深入浅出 JavaWeb:Servlet 再说几句
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- 必会必知git
git必会必知 1 前言 git前身是BitKeeper,但是他不是开源软件,不符合当时开源趋势,于是就会有了开源的git,git开发只用了十天时间.目前git是公司开发必不可少的一个工具,用于多 ...
- JavaWeb—Servlet
1.什么是Servlet 用来扩展web服务器功能的组件——早期的web服务器只能处理静态资源的请求,即需要事先将html文件准备好,并存放到web服务器上面.不能够处理动态资源的请求(需要计算,动态 ...
- JavaWeb:Servlet技术
JavaWeb:Servlet技术 快速开始 Servlet是什么 Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 ...
- Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)
转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问对于可以静态化的页面,尽可能静态化对一个动态页面中可以静态的局部,采用静态化部分数据可以生成XML,或者文本文件 ...
- 图解 & 深入浅出 JavaWeb:Servlet必会必知
从[JavaEE 要懂的小事] Http相关,一直想写点Web开发相关的.最近项目接口开发紧,还有准备新的九月份战斗.JDK IO源码就隔一段落,温故知新看看Servlet & JSP 相关. ...
- 图解 & 深入浅出JavaWeb:事务必会必知
事务,大家所熟悉的事务(Transcation),基本上会就往Spring事务靠.其实Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring事务管理的基础.这篇总结 ...
- javaweb阶段几个必会面试题
1.jsp的9大隐式对象 response(page):response对象是javax.servlet.http.HttpServletResponse对象的一个实例.就像服务器创建request对 ...
- 数据库必会必知 之 SQL四种语言:DDL DML DCL TCL
作者:泥瓦匠 今天群里面讨论,DDL 还是 DML,我这种小白还是总结下他们的区别吧. 1. DDL - Data Definition Language 数据库定义语言:定义数据库的结构. 其主要命 ...
随机推荐
- [51Nod 1584] 加权约数和
Description 在整理以前的试题时,他发现了这样一道题目:"求 \(\sum\sigma(i)\),其中 \(1≤i≤N\),\(σ(i)\) 表示 \(i\) 的约数之和.&quo ...
- python 模块之-json
python 模块json import json x="[null,true,false,1]" print(json.loads(x)) #---------------- ...
- Java 属性映射(DozerBeanMapper)
package com.kps.common.utils; import java.util.ArrayList; import java.util.Collection; import java.u ...
- C - A Simple Problem with Integers POJ - 3468 线段树模版(区间查询区间修改)
参考qsc大佬的视频 太强惹 先膜一下 视频在b站 直接搜线段树即可 #include<cstdio> using namespace std; ; int n,a[maxn]; stru ...
- Codeforces1023F Mobile Phone Network 【并查集】【最小生成树】
题目大意: 给一些没安排权值的边和安排了权值的边,没被安排的边全要被选入最小生成树,问你最大能把它们的权值和安排成多少.题目分析:假设建好了树,那么树边与剩下的每一条边都能构成一个环,并且非树边的权值 ...
- 洛谷p1586四方定理题解
题目 这个题的本质是动态规划中的背包问题. 为什么会想到背包呢. 因为往往方案数不是排列组合就是递推或者是dp,当然还有其他的可能.我们可以把一个数的代价当成这个数的平方,价值就是一个方案数.由于这个 ...
- Django+Xadmin打造在线教育系统(六)
讲师相关功能实现 拷贝并修改teacher-list.html和teacher-detail.html, 继承base模板 # 讲师列表 path('teacher_list/', TeacherLi ...
- bzoj 1067: [SCOI2007]降雨量 (离散化+线段树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1067 思路: 毒瘤题,写的自闭,改了一晚上,注意要理清题目的逻辑 x小于等于y,x,y之间的 ...
- MT【288】必要性探路
已知$f(x)=e^x-\dfrac{1}{2}ax^2-b$(1)当$a=1,b=1$时,求$f(x)$在$[-1,1]$上的值域.(2)若对于任意实数$x$,$f(x)\ge0$恒成立,求$a+b ...
- 设置服务器的MySQL允许远程访问/外网访问
我需要在C++中连接服务器上的MySQL数据库.但是直接连接失败了,原来服务器上还要修改一下MySQL的配置. 一.服务器上的配置mysql数据库 进入mysql: mysql -uroot -p 输 ...