Servlet详解

本文详细介绍了Servlet的概念,包括Servlet是什么以及开发Servlet的步骤。通过实例演示了如何手动编写Servlet,从实现Servlet接口到配置对外访问路径。接着探讨了Servlet的调用过程、生命周期,以及在Myeclipse中开发Servlet的详细步骤。文章最后分析了Servlet的继承结构和对外访问路径的配置细节,帮助读者全面掌握Servlet开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Servlet概述

1.1. Servlet概述

1.1.1. Servlet是什么

Servletsun公司提供的一门用于开发动态web资源的技术。

按照这套规范写出来的Servlet可以放置到web应用中在Servlet容器中运行。

1.1.2. 开发Servlet步骤

想要开发一个Servlet只需要两个步骤:

(1)写一个类实现javax.servlet接口。

(2)web.xml中为servlet配置对外访问路径。

2. 开发第一个Servlet

2.1. 写一个类实现Servlet接口

2.1.1. Servlet接口api

接下来我们就手动编写一个Servlet感受一下Servlet开发的过程。

我们用记事本,写一个类实现Servlet接口,我们打开api发现如果直接实现Servlet接口需要实现如下方法,如图-1所示:

 

-1

简单介绍下其中重要方法:

init(ServletConfig config)

初始化方法,会在Servlet被创建出来后立即执行,做一些初始化的工作

destroy()

销毁方法,会在Servlet被销毁之前执行,做一些善后工作

service(ServletRequest req, ServletResponse res)

服务方法,每当有请求访问Servlet时,此方法执行,处理请求的代码要写到这个方法里。

2.1.2. GenericServlet抽象类

我们发现这个接口中方法太多了,其实我们可以直接继承Servlet接口的一个默认实现了GenericServlet类,如图-2所示:

 

-2

通过观察api,我们发现GenericServlet是个抽象类,实现了Servlet接口中的大部分方法,唯独service方法没有做实现,我们继承GenericServlet需要实现这个Service方法在其中写处理请求的代码。如图-3所示:

 

-3

在记事本中编写如下代码,注意写的过程中需要导入包。如图-4所示:

 

-4

我们输出当前时间到客户端,service方法有两个参数,ServletRequest代表HTTP请求,ServletResponse代表HTTP响应,我们想要获取客户端发送过来的信息时可以找ServletRequest,现在需要向客户端发送数据就可以使用ServletResponse对象。

通过查询ServletResponse对象的api,发现其中有获取写出数据的流的方法,通过这个方法获取流就可以将数据发送给浏览器。代码如图-5所示:

 

 

-5

编写好java文件后,需要进行编译,如图-6所示:

 

-6

在编译的过程中发现少了开发包,这是因为我们现在开发的是javaee项目,需要将javaee相关的开发包加入classpath环境变量,这个包在tomcat的支持包中存有,将其加入classpath环境变量即可。如图-7所示:

 

-7

再次编译。

报出了警告,是因为DatetoLocaleString方法已经过时,但是我们不关心,到此编译已经完成。编译成功后将包拷入web应用的WEB-INF/classes目录下,如图-8所示:

 

-8

 

2.2. 配置Servlet的对外访问路径

2.2.1. 在web.xml配置servlet

我们还需要在web.xml中为这个Servlet配置一个对外访问路径。

打开web.xml文件,在根标签下进行如下配置,如图-9所示:

 

-9

其中,servlet-class中为配置的Servlet类的全路径名。

servlet-name是为该servlet配置的名称,此名称没有特殊要求,为了便于识别此处取名和类名相同。

url-pattern是为该名称的servlet配置对外访问路径,浏览器可以通过该路径访问此servlet

启动服务器,通过浏览器访问,如图-10所示:

 

-10

发现成功输出了当前时间,多次刷新页面发现每次显示的都是最新的时间,不同的人在不同的时间看到的结果不同,说明这确实是一个动态web资源。

3. Servlet的调用过程和生命周期

3.1. servlet的调用过程

3.1.1. Servlet调用过程图

当我们在访问这个Servlet时,是如何看到时间输出的呢?整个过程是如何工作的呢?我们画图解释,如图-11所示:

                                                                                      7 

-11

1)在浏览器输入地址,浏览器先去查找hosts文件,将主机名翻译为ip地址,如果找不到就再去查询dns服务器将主机名翻译成ip地址。

2)浏览器根据ip地址和端口号访问服务器,组织http请求信息发送给服务器。

3)服务器收到请求后首先根据Host请求头判断当前访问的是哪台虚拟主机。

4)服务器根据http请求头中的请求URI判断当前访问的是哪个web应用。

5)服务器根据http请求头中的请求URI判断当前访问的是web应用中的哪个web资源。

6)检查web应用的web.xml文件,如果根据路径找到具体的servlet处理类的全路径名交给该servlet处理,如果找不到就交给缺省servlet处理。

7)这个过程中浏览器只知道自己发出来http请求,不久就收到了http响应,浏览器不知道也不关心服务器内部是如何处理的。浏览器和服务器之间的关系是非常单纯的,只有HTTP协议。

8)解析请求、封装RequestResponse对象、创建Servlet、调用Service方法都是服务器自动进行的,开发人员只需要写好Servlet配置进容器中即可,无需操心具体的底层实现。---这就是容器啊!多重要!多形象!

3.2. servlet的生命周期

3.2.1. servlet生命周期详解

1Servlet第一次被访问到时创建对象,创建出来后立即执行init方法执行初始化的操作。

2)从此以后该对象一直驻留在内存中为后续的对这个Servlet的请求进行服务。

3)直到服务器关闭或web应用移除出容器时,随着web应用的销毁Servlet对象销毁掉,在销毁之前调用destory方法执行善后工作。

4)在存活期间,每次对Servlet 的调用都会导致Service方法的执行。

4. 在myeclipse中开发Servlet

4.1. 为什么需要myeclipse

4.1.1. 为什么需要myeclipse

上面的例子中我们用记事本实现了一个Servlet,这样做的目的是为了让大家更好的理解Servlet的本质,但是如果在真实开发中也用记事本开发,可以想见效率一定是非常低的。接下来我们来了解一下如何在Myeclipse环境中开发Servlet

4.2. 在Myeclipse中开发Servlet

4.2.1. 第一步:创建servlet

在工程src目录上右键弹出菜单,选择new->Servlet,如图-12所示:

 

-12

4.2.2. 第二步:配置servlet类信息

在弹出的对话框中输入Servlet的包名、类名,默认继承HttpServlet,覆盖其中doGetdoPost方法。如图-13所示:

 

-13

4.2.3. 第三步:配置serlvet虚拟路径

进入下一界面,选择是否自动配置servletweb.xml中,一旦勾选,则自动会用输入的信息在web.xml中为该Servlet配置对外访问路径,如图-14所示:

 

4.2.4. 第四步:编写servlet处理逻辑

点击确定,创建出Servlet,发现该类继承了HttpServlet(此类是Servlet接口的实现类,我们的类继承他,自然也是个Servlet),并且覆写了其中的doGetdoPost方法。

当客户端用get方式访问该Servlet时会导致doGet方法执行

当客户端用post方式访问该Servlet时会导致doPost方法执行

我们只需要写代码处理对应的处理逻辑即可。

很多时候我们的处理代码对于get方式的请求和post方式的请求的处理是相同的,此时可以在doPost中调用doGet();然后将处理代码写在doGet中。这样无论是get还是post请求都可以进行处理了。

编写代码,如图-15所示:

 

-15

4.2.5. 第五步:将web应用发布到tomcat

如图-16所示:

 

-16

启动tomcat,如图-17所示:

 

-17

4.2.6. 第六步:通过浏览器访问

由于web应用是发布到了webapps中即localhost虚拟主机中,所以按照如下方式访问,注意此处的/Demox不是工程名,而是发布时的指定的web应用名,如图-18所示:

 

-18

通过浏览器访问,如图-19所示:

 

5. Servlet的继承结构

5.1. Serlvet继承结构

5.1.1. 概述

我们在手写Servlet时继承的是GenericServlet,而用Myeclipse生成的Servlet是继承了HttpServlet,那么他们之间的关系到底是什么样的呢?下面我们讨论下Servlet的继承结构:

5.1.2. Servlet接口

定义了一个servlet应该具有的方法,所有的Servlet都应该直接或间接实现此接口

5.1.3. GenericServlet抽象类

GenericServlet抽象类是对Servlet接口的默认实现,对Serlvet接口中的大部分方法都做了默认实现,只有service方法是一个抽象方法需要继承者自己实现。实现者只需要实现Service方法在其中写处理请求的代码即可。

5.1.4. HttpServlet

继承自GenericServlet类,在GenericServlet类的基础上对HTTP协议进行了优化,并且实现了其中的service抽象方法,在其中判断了请求的请求方式,并根据请求方式的不同分别调用不同的doXXX()方法。

通常我们在开发Servlet时,直接继承HttpServlet覆盖对应的doGet()doPost()方法即可,一般不推荐直接覆盖service()方法。

6. Servlet对外访问路径配置细节

6.1. Servlet配置细节

6.1.1. 基本配置

Servlet需要在web.xml中配置对外访问的路径。如图-20所示:

 

-20

其中:

<servlet>标签配置Servlet

<servlet-mapping>标签配置该Servlet的对外访问路径。

一个<servlet>可以对应多个<servlet-mapping>

6.1.2. 星号匹配符的使用

可以用*通配符配置<serlvet-mapping>,但是要注意,必须是 *.后缀 或者 /开头的以/*结尾的路径。

由于匹配符的引入有可能一个虚拟路径会对应多个<servlet-mapping>,此时的匹配优先原则为:哪个最像找哪个,*.后缀 优先级最低。

思考:

对于如下的一些映射关系:Servlet1 映射到 /abc/* Servlet2 映射到 /* Servlet3 映射到 /abc Servlet4 映射到 *.do 问题:当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应 Servlet引擎将调用Servlet1当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应 Servlet引擎将调用Servlet3当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应 Servlet引擎将调用Servlet1当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应 Servlet引擎将调用Servlet2当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应 Servlet引擎将调用Servlet2

 

6.1.3. 缺省Servlet

路径中有一个特殊的配置“/,如果一个servlet的对外访问路径被设置为/,则该servlet就是一个缺省servlet,其他servlet不处理的请求都由它来处理。

conf/web.xml(通用web.xml,参考tomcat章节)中配置了缺省servlet,对静态资源的访问和错误页面的输出就是由这个缺省servlet来处理的。

如果我们自己写一个缺省servlet把爸爸web.xml中的缺省servlet覆盖的话,会导致静态web资源无法访问。所以不推荐自己配置缺省Servlet

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值