天天看点

图解 & 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

“眨眼间,离上一篇写技术博文时隔1个月。怕自己真的生疏了,都是备案太慢惹得。哈哈,继续high~ ”

图解 & 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

http服务器是web服务器的一种,也是开发最常见的,自然还有其他方式进行信息交互,比如ftp文件服务器…

web服务器是可以向发出请求的浏览器提供文档的程序。其核心过程为     连接过程 — 请求过程 — 应答过程 — 关闭连接

这让我想到了tomcat架构的一张图:

图解 & 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

如图,tomcat 包含了核心服务模块:connector连接模块 和 container 容器。tomcat server 核心是一个 servlet/jsp container。对每一个http请求,过程如下

— 获取连接 — servlet来分析请求(httpservletrequest) — 调用其service方法,进行业务处理 — 产生相应的响应(httpservletresponse) — 关闭连接

如图:

图解 & 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

蓝色线指向过程是请求,绿色线指向过程是响应过程。也就是上面web服务器核心过程:“连接过程 — 请求过程 — 应答过程 — 关闭连接”

什么是servlet?(每次都会不停的问自己,这是什么“what”?紧接着应该是什么用“how”吧)

“servlet 是运行在web服务器的java小程序。servlet可以获取并针对web客户端的请求作出响应。一般情况下,通过http,即超文本传输协议,进行传输通信。” 1 <code>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.</code>

所以,servlet 是web服务器核心工作的抽象。它不单单只是实现httpservlet,可能实现有ftpservlet(这个我猜的)等。相对较多的web开发,知道的肯定是httpservlet。

“httpservlet 提供了一个能被继承后创建一个适应web网站的http servlet的抽象类。” <code>provides an abstract class to be subclassed to create an http servlet suitable for a web site.</code>

光说不练假把式,练一个“hello,servlet/jsp world!”:

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

<code>import</code> <code>java.io.ioexception;</code>

<code>import</code> <code>java.io.printwriter;</code>

<code>import</code> <code>javax.servlet.servletexception;</code>

<code>import</code> <code>javax.servlet.annotation.webservlet;</code>

<code>import</code> <code>javax.servlet.http.httpservlet;</code>

<code>import</code> <code>javax.servlet.http.httpservletrequest;</code>

<code>import</code> <code>javax.servlet.http.httpservletresponse;</code>

<code>/*</code>

<code> </code><code>* copyright [2015] [jeff lee]</code>

<code> </code><code>*</code>

<code> </code><code>* licensed under the apache license, version 2.0 (the "license");</code>

<code> </code><code>* you may not use this file except in compliance with the license.</code>

<code> </code><code>* you may obtain a copy of the license at</code>

<code> </code><code>* unless required by applicable law or agreed to in writing, software</code>

<code> </code><code>* distributed under the license is distributed on an "as is" basis,</code>

<code> </code><code>* without warranties or conditions of any kind, either express or implied.</code>

<code> </code><code>* see the license for the specific language governing permissions and</code>

<code> </code><code>* limitations under the license.</code>

<code> </code><code>*/</code>

<code>/**</code>

<code> </code><code>* @author jeff lee</code>

<code> </code><code>* @since 2015-6-25 19:46:45</code>

<code> </code><code>*  hellowrold案例</code>

<code>@webservlet</code><code>(urlpatterns = </code><code>"/helloworld.html"</code><code>)</code>

<code>public</code> <code>class</code> <code>helloworldservlett </code><code>extends</code> <code>httpservlet{</code>

<code>    </code> 

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>long</code> <code>serialversionuid = 1l;</code>

<code>    </code><code>@override</code>

<code>    </code><code>protected</code> <code>void</code> <code>doget(httpservletrequest req, httpservletresponse resp)</code>

<code>            </code><code>throws</code> <code>servletexception, ioexception{</code>

<code>        </code><code>// 获取输出打印对象</code>

<code>        </code><code>printwriter out = resp.getwriter();</code>

<code>        </code><code>out.println(</code><code>"hello,servlet/jsp world!"</code><code>);</code>

<code>    </code><code>}</code>

<code>}</code>

右键该helloworldservlett.java文件 — run as — run on server — 选择tomcat服务器 — finish即可

图解 &amp; 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结
图解 &amp; 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

等待片刻,你可看到网页上如下输出。这就是客户端从httpservlet获取到的响应:

图解 &amp; 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结
休息一下吧~ 看看小广告:

<code>@webservlet(urlpatterns = "/helloworld.html")</code>

@webservlet 注解用于声明一个httpservlet的配置。其中,urlpatters = “/helloworld.html”,urlpatterns复数形式,说明至少一个url必须被申明。它和另一个value必须存在一个,但不能同时存在。如果要匹配多个url路径的话,如下:

<code>@webservlet(urlpatterns = { "/helloworld01.html", "/helloworld02.html" }</code>

下面有个@override,重写了父类httpservlet的doget方法。我们先看看父类httpservlet。httpservlet是一个抽象类,它提供了以下方法:

— doget  , 服务于 htpp get 请求 — dopost , 服务于 http post 请求 — doput  , 服务于 http put 请求 — dodelete,服务于 http delete 请求 …
图解 &amp; 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

对于不同的请求,httpservlet的子类必须相应的实现至少一个方法,通常来说,会是其中一个,这样代码比较清晰。那父类的doget方法做了什么工作呢?

<code>protected void doget(httpservletrequest req, httpservletresponse resp)</code>

<code>        </code><code>throws servletexception, ioexception</code>

<code>    </code><code>{</code>

<code>        </code><code>string protocol = req.getprotocol();</code>

<code>        </code><code>string msg = lstrings.getstring("http.method_get_not_supported");</code>

<code>        </code><code>if (protocol.endswith("1.1")) {</code>

<code>            </code><code>resp.senderror(httpservletresponse.sc_method_not_allowed, msg);</code>

<code>        </code><code>} else {</code>

<code>            </code><code>resp.senderror(httpservletresponse.sc_bad_request, msg);</code>

<code>        </code><code>}</code>

这里就简单的获取了下http协议及http local信息,然后可以协议是否是1.1,做出分别是405或者400http状态码的响应。

回到helloworldservlett.java 这里:

<code>@override</code>

<code>        </code><code>throws servletexception, ioexception {</code>

<code>    </code><code>// 获取输出打印对象</code>

<code>    </code><code>printwriter out = resp.getwriter();</code>

<code>    </code><code>out.println("hello,servlet/jsp world!");</code>

表示该helloworldservlett会接受http get请求,并oom到httpservletrequest,并执行里面的逻辑代码和返回响应。 这里从httpservletresponse对象中获取到输出打印对象printwriter,然后输出了“hello,servlet/jsp world!”。

完毕!哦还有一点补充补充补充:

print,这里还好一句话。如果打印个table会很麻烦,因此有一个jsp的东西出现了,是servlet的html化身。

又回到这个简单的 get servlet代码:

<code>public class helloworldservlett extends httpservlet{</code>

<code>    </code><code>private static final long serialversionuid = 1l;</code>

<code>    </code><code>protected void doget(httpservletrequest req, httpservletresponse resp)</code>

<code>            </code><code>throws servletexception, ioexception{</code>

<code>        </code><code>out.println("hello,servlet/jsp world!");</code>

这过程总结如下:

— 从浏览器(client)获取连接”/helloworld.html” — tomcat connector模块将请求(request)传递给 container模块 — container 模块会做以下事情 —— 分析htpp请求信息,组装成httpservletrequest对象 —— 创建新的httpservletresponse对象 —— 根据路由配置,搜索相应的servlet,并创建一个线程用于处理本次请求。此时线程会将上面request和response对象的索引,传递给servlet — 新线程中的servlet处理逻辑 — 线程结束后,通过httpservletresponse对象的printwriter,返回浏览器一个信息

过程图如下:

图解 &amp; 深入浅出 JavaWeb:Servlet必会必知一、Web服务器二、Tomcat 简单说几句三、我第一个Servlet三、分析源码五、深入Servlet 具体过程六、小结

蓝色线指向过程是请求,绿色线指向过程是响应过程,橙色线指向过程是内部处理过程。

有些面试题会这样问:

servlet是线程安全的吗? 不是,一个servlet实现类只会有一个实例对象,多个线程是可能会访问同一个servlet实例对象的,线程安全问题都是由全局变量及静态变量引起的。

因此,servlet对象实例化是在以第一次请求此servlet时,如果访问后,实例对象存在内存中,只会在服务器停止时,它才会消失。它不会随着各个线程结束而结束。因此下次访问servlet时,servlet container会搜索相应的servlet,如果不存在,container新建相应的servlet。这也是我们想要的结果。

发现这一博客写的太多,回头一看。可以写成三个文章了。言归正传本文要点如下

1、简单介绍web服务器 及 tomcat容器 2、第一个sevlet的开发及使用 3、深入源码及api介绍使用 4、总结一次请求及响应的真实过程