Servlet1

前言(Preface)

  • Servlet做为浏览器与服务器交互的技术,把浏览器,服务器,数据库,这三者相互串接起来,是整个Web项目的核心技术。
    web项目之java实现

1.What is Servlet(academia)

  • Servlet这个单词,它本来是没有这个词,它是俩词组合在一起,它是Server let,然后呢,拼在一起缩写成为Servlet,这样,就拼了一下,这样拼的Server是服务器,let是片段,你可以查一查,程序片段,连在一起呢,是服务器端的程序片段,服务器端的小程序啊。

  • Sun当初呢,在推出这项技术的时候,也没有考虑那么多,它就觉得我要做,做这么一个东西,解决项目,企业中的一些问题啊。它当初是按小程序来想的,结果一下做大了,不小心做大了,所以,当初命名时叫服务器端的片段小程序,现在来看,那不应该这么叫了,它还能做很多的事情,那么,总之这个单词,就是这么个东西啊,咱们不用纠结于表面的意思,没什么意思,我们得看它的本质,它到底能干什么啊,这个很关键。

  • 这项技术,它怎么用,但我觉得呢,怎么用,被人教你一遍,这么一写就会了,其实没什么难的,那在于什么呢,就是说一定要理解,这项技术,它到底,本质上是解决什么问题,就为什么会有这项技术,我们什么时候要用它,这个很关键,如果这一点没搞清楚的话,
    工作时很容易就会,这个思维就会混乱,我为什么要这个东西呢,我这个需求需不需要用呢,搞不清楚啊,我们首先要搞清楚,到底什么时候用它,这个很关键,那么一般的书上,给我们介绍了这项技术啊,它上来说了这样一句话:
    在这里插入图片描述

  • 说什么是Servlet,它说,这个技术呢,是Sun,或者是Oracle,因为被收了,是吧,Sun被收购了,它是Sun公司呢,制定的一种用来扩展,Web服务器功能的组件规范,能看明白么,能理解么,能个屁啊,我都看不明白 ,你还能,你给我解释解释啊,什么叫web服务器,什么叫组件,什么叫规范 ,你都看懂了,是不有点太狂了吧,我都看不明白,你别扯了啊,反正还挺配合啊,谢谢谢谢,挺配合,
    不过你配合的有点太,太离谱了啊,没明白就没明白,没有必要非得硬说明白,这句话,太抽象了,一般不好明白。

  • 这个书上啊,写的时候呢,更专业化,更学术化,很多这个语言呢,是从某篇书上,或者说谋篇百科上,给它拷过来的,可能是Sun官方的一个解释,大家把那个解释互相copy过来,就是这样,但这个解释呢,是专业的技术人员,给别人的解释,它太抽象了,不好理解,所以我们还是别去,这么去看这句话,我们换个角度去理解,从通俗角度去理解,而不是背这句话,背这句话,一点用都没有。

2.PreparedWorks

  • 怎么理解Servlet,首先探讨这样一个话题,什么话题呢,我们知道浏览器访问服务器,这个网页应该事先存到服务器上,网页应该存到服务器上,那浏览器访问服务器,会得到一个网页,那服务器,它怎么就给浏览器返回一个网页,探讨这样一个话题,就是服务器如何给浏览器返回一个网页,这中间有什么套路,当然,我不是说把这个流程说的那么细,就说个大概,我们去体会其中的,某一些关键点,去体会:

准备知识1:静态网页与动态网页

  • 那服务器要给浏览器返回一个网页,这个网页有两种形式,第一种形式,我称之为,静态网页,第2种形式,我称之为什么啊,就动态网页,是相反的。(那大家想一想啊,或者你给我举个例子,你觉得什么样的网页是静态的,什么是动态的,你觉得,你给我举个例子就行,你说哪个网页是静态的,哪个是动态的,我说举个例子,能听明白我的话么,还能聊天么,我说给我举个例子,什么叫举个例子,你说淘宝,比如说京东,比如说百度,明白这意思吧,你给我举个实际的例子,就好了,啊,我是启发一下你,你随便举,你说这个,哪个网站,你感觉它是内容是静态的。百度是静态的,为啥百度是静态的啊,因为简单,只有字,能看对吧,你这有点扯,百度要是静态的话,你想啊,那我搜一个词,和你搜一个词,这个结果一样么,我搜张三,你搜李四,咱俩结果不一样啊,我搜什么出什么,结果是有变化的,是不是,它应该不是静态的。)
  • 什么样的是静态的呢,比如开发文档啊,像w3school那样的文档,那个是静态的,那个是写死的,就是一个静态网页完了,开发手册网页,那个手册,那些内容是固定的,是静态的,还有别的么,也很好想,还有我们看的什么,百度百科,那篇文章,是不是那每个人看,比如说,咱们搜到了一个百度百科的文章,宫保鸡丁的做法,每个人看有区别么,没有区别吧,百科。还有么,小说,小说也算,还有么,什么新闻。就什么样的网页是静态的呢,就这些内容,无论谁去看,得到的结果都一样,这就是静态的,反之什么是动态的呢,每个人看,是有差异的
  • 当然,有人会说百科,感觉它也是动态的,因为百科能登录,登录完上面显示,欢迎你,某某某,那个某某某,每个人是不一样的,我登录,欢迎你李洪鹤,你登录,欢迎你谁谁谁,不一样,就有区别,所以它一定是动态的,不然怎么会有区别呢。
  • 还有小说,那其实,怎么说呢,咱们现在看一个,去网上找一个纯静态网页,还真挺少的,因为啥,即使是小说网站,它有广告吧,新闻也有广告,百科能登录,还有那个,开发也有广告,w3c,那个网站,也有广告,而且你要细心的话,你会发现,那广告是会变的, 不同人,看这广告不一样,我上去看这广告就是 ,比如说电饭锅,你上去,看就是鼠标,你喜欢啥,你搜个啥,它就推荐啥,它也是动态的。
  • 所以说你现在找一个纯静态的网页,还挺少的,我就说这个意思,能理解就可以了。那么,至于说广告,它凭什么能知道你想要什么,向你推荐,你喜欢的东西呢,这以后再说,先不着急啊,总之,就是解释一下,其实我们说的这个东西,也不是绝对严谨,大概这个意思,了解一下。
  • 还有淘宝是动态的,因为淘宝也能登录,再一个你用淘宝,你也有这样一个感觉,就是我上淘宝,它老向我推荐,比如说,电饭锅,你上淘宝,老向你推荐,游戏鼠标,为啥呢,因为我最近搜过电饭锅,你搜过鼠标,它是因人而已,推荐的东西,它有差异的,是动态的。
  • 还有比如说 微博,肯定是动态的,你看我关注的是苍老师,你关注的是凤姐,我们一刷新一看啊,人就不一样,那不一样,有差异。
1) 服务器处理静态网页和动态网页的对比

概括一下:

  • 什么样的网页,是静态的呢,就是,无论谁看,结果都一样,那它就是静态的,这个静态不在于说,它能不能动,比如说,我们打开一个网页,网页上是一个视频,那谁看这个视频,都是同一段,它也是静态的,如果挂的是视频,视频是可以动,你也可以点,你也可以快进,但是呢,谁看都是这个视频,它也是静态的,一成不变的东西,就是静态的。
  • 什么是动态的呢,就是每个人看的结果,有差异,不同,那就是动态的,并不难理解。有人说,你说这个有什么意思呢,那有意思啊。
  • 静态网页你想啊,静态网页服务器怎么处理呢。这种情况呢,服务器直接保存一份HTML就可以,然后呢,并向浏览器,发送此html,如果是静态网页,服务器存的就是一份固定的html,谁要就给它这份html,就完了,很容易;
  • 但如果是动态网页,你想一想,服务器直接存一个写死的html,能行么,可能每个人看结果不一样么,不能对吧,它就不能是html了,那服务器里存个什么东西呢,动态网页啊,这个服务器保存一个对象,然后呢,由它,由这个对象啊,动态拼一个网页,发送给浏览器,好,这句话,比较关键,你想一想,你不用去深究,就理解它表面肤浅的意思,这个对象,它怎么写的,怎么去拼啊,那是后话。总之,服务器想给你返回一个动态网页,它存的不是html,它存的是一个对象,那这个对象,用这个对象动态拼个网页,你想要苍老师的内容,我给你拼苍老师,你想要凤姐的内容,给你拼凤姐,根据你的喜好,给你拼一个网页 ,动态的。
  • 那么在不同的语言当中呢,这个对象不一样,java里,.net里,php里就不一样啊,那别的语言,就不探讨了,只探讨java语言,那么在java语言当中,该对象是什么呢,它就是叫做Servlet,就是说,你并不是随便写个对象,都能拼网页,这个对象必须有一定的要求,那这个Servlet,就是对这个对象的要求,Servlet就是什么呢,就是满足要求的对象,它有能力拼出网页来。
2) 实际工作中的网页与Servlet的关系
  • 大概的概括一下,Servlet这个东西,它是个什么,它能干什么,Servlet,它就是个对象,这个对象不是我们随便写的,是需要满足条件的,有要求的,要求是什么,这是后话;Servlet,它能拼一个动态网页,所以说Servlet就是用来拼动态网页的。如果说我们工作时,我们的项目中,没有动态网页,我需要用Servlet么,不需要,如果有动态网页,需要用么,就必须需要。
  • 工作时,我们做的项目是动态网页多呢,还是静态网页多呢,为什么是动态多呢,高效低耦,你这都扯上去了,我问你这用的这个频率的场景,不是问你这个语言,这个优缺点啊,你都扯那去了,扯太远了。其实得看项目啊,有的项目,比如说,一个企业的官网,就是对企业宣传介绍,比如说企业的首页啊,什么关于我们,我们的产品,我们的团队啊,什么招聘等等,那样的网站,那都是纯静态的,一个动态东西都没有,也不用登录,也没有注册,什么都没有,就看,静态的,也有的软件呢,是动态的,像淘宝啊,京东啊,等等。
  • 我们做的项目是动态网页,还是静态网页多呢,一定是动态的。我这么跟你讲吧,你就不可能,你要去做一个全静态网页的项目,为啥呢,如果说,我们做一个企业官网,全都是静态网页的话,没有人会招一个java程序员去做,因为那个东西,美工就能做,或者说随便上市场上找个人,找个私活,或者买一个,那玩应也就几千块钱,不值钱,它招你一个java程序员做这个项目,赔了,月月给你开个五六千块钱,一个月工资就够做这个项目了,养活不起你,所以说,不可能让你做那个东西,我们去做的话呢,一定是去做一些商业系统,一定几乎全都是动态网页 ,而且静态网页是很少的,都是动态的内容, 所以基本上,都是做 动态网页,都会用到Servlet,很少会做纯静态网页 ,或者说呢,有的项目静态网页多,动态网页少,那这种项目呢,一般也不用java做,因为什么呢,它用php做,就可以了,php适合做这种小项目,快,做个论坛啊,做个什么东西,快啊,但是做一些复杂的商业系统,像什么财务啊,人力啊,OA啊,供应链啊,什么预算啊,等等这些系统,那都得用java做,当然 .net 也可以,但 .net 呢,因为它不能垮平台,不构成竞争,所以呢,咱们这个Java,我们工作时,一定主要是做动态网页,静态网页是很少的。

准备知识2:组件与Servlet的特征

什么是Servlet,不能说什么是Servlet,是Servlet的特点,就特征吧,根据之前对它的描述,归纳出它的特征。

  • 第一点,它是一个对象,它还得满足一定的规则,满足一定的规范,那么它是满足规范 的对象,那么,满足规范的对象,我们给它起一个学名,也叫组件,满足规范的对象,通常叫组件,没有规范,就叫对象 ,有了规范,叫组件,这就是个名词,就习惯于这么叫,我们说对象,说这东西是对象,感觉很普通,说叫组件,感觉我们比较专业,有这种感觉;
  • 然后第二点,其一,Servlet这个对象,这个规范,由谁来定的呢,是由Sun定的,满足Sun的规范的对象,叫做组件。其二,这个对象,将来要存到哪去,它要存在服务器上,服务器保存一个对象。那至于如何存储,这是后话。
  • 最后,最关键的一点,这对象能干什么,它可以动态的拼资源,什么是资源,网络上,我们一切可见的内容都叫资源,我们往小了说,它能拼网页,往大了说,它能拼资源,互联网上,我们能见的一切东西,它都能拼出来,比如说,网页,它能拼出来,比如说,图片,它能拼出来,等等,都能拼出来,视频,视频的话,如果你有,你能写出那个代码,也能拼出来,但是,那个东西,它不是那么好拼的,有点扯啊,一般,视频不会拼的,视频都是拍出来,你把它播放一下,没有人说用代码去拼视频,这个玩应有点,有点太,太离谱了啊。拼个图片还是有可能的。但不管怎么说吧,就是这个对象,它能拼出资源来 。
  • 那你比如说,我这个浏览器 ,我只想要一个,不是网页,我只想要一个word,word能拼出来,我想要一个XML,能拼出来,都可以,我想要一个Excel,也能拼出来,就是一切内容,它都能拼出来,我想要一个邮件,也可以拼出来,它能拼出一切东西,都可以。那么笼统说呢,叫拼资源,那这件事,还有一个术语,就是动态拼资源这件事,也有一个术语,术语叫什么呢,叫处理http协议,因为怎么去拼资源这件事,是由这个协议规定的,那么它拼出资源的过程,就是处理这个协议的过程,用术语来表示,就是处理http协议,是这样的。

3.What is Servlet(simple)

  • 仅仅通过言语,能理解Servlet到什么程度,是什么程度,肯定是没有办法,100%的把它理解到位,因为毕竟还没有见到这个东西,怎么写,怎么做,怎么去操作,所以,会感觉这个,有点地方比较不太踏实,正常,有了大概有所了解,后面的话,后面的内容,主要是验证这件事,告诉你怎么去做,实现这些事,是这个意思。那么有了Servlet的三个特点以后 ,最后就可以再推一下,推出什么呢,那到底什么是Servlet,再给它下一个定义,那这个定义呢,是基于我们的理解去推导出来的,是比较,就是比较相对容易记一点,但是,重点在于前面这个理解,理解最重要,这个定义不用死记硬背,甚至不用背,也没关系:
  • 那什么是Servlet,一句话,它是Sun推出的,因为你看它不是Sun的对象吗,Sun给规定的对象么,所以它是Sun推出的;用来在服务器端,它都存在服务器上,解决呢,是服务器上的逻辑,是sun推出的,用来在服务器端,用术语来讲处理HTTP协议的;最后,它到底是个什么东西,是个对象,学名叫组件;你把这些特质揉在一起,把语言整理一下,就得出这样一个结论:
  • 它是sun推出的,用来在服务器上,处理 HTTP 协议的组件。它就是这么一个东西。那总而言之呢,Servlet它是什么呢,它就是一个组件,本质上就是一个对象,这个对象的作用,往好听了说,处理协议,往low了说,能拼个网页,就行了,那不用说,非得说的多高端,你就能记住,这能拼个动态网页,先把这个能理解了,就OK了,先到这种程度。

4.服务器Tomcat

理解了什么是Servlet,上来就说,如何开发一个Servlet,跨度太大了,在说开发之前,我们需要呢,这个放慢节奏,先说一下什么是服务器,具体细节见 WebServer 服务器Tomcat。

5.小总结

  • 综上所述已经了解了Servlet这个对象,它是一个组件,因为它必须运行在服务器上,只有服务器才能运行它,从而引出了服务器。在正式的项目中,要访问对象,要调用对象,不是写个main方法测一下就ok了,而是通过浏览器,访问服务器,通过服务器访问那个对象,是这样一个过程,所以必须有服务器。而服务器像浏览器一样,是一个软件,有很多种,比如tomcat;服务器既可以单独使用,又可以通过开发工具,比如Eclipse,去管理使用。服务器的安装,使用和配置的步骤,在不同的操作系统,比如Linux和Windows也有所区别。
  • 以Tomcat服务器为例,如果说,你不用的时候,一定要把Tomcat关了,如果不关的话,始终开着Tomcat,再开一遍,就会有冲突,会有问题。而关掉了Tomcat,再去通过http://localhost:8080,去访问它,就什么都看不到了,访问不到了,服务器启动,就能访问。那服务器启动时,如果服务器内部有项目,我们就可以访问服务器的项目,就是这样,比如我们访问淘宝,京东等等,各种网站,都是这么干的,它们都会有一个服务器,当然可能是Tomcat,可能是WebLogic,也可能是其他的什么什么,那么它写的软件在那个服务器里运行就好了。

6.Servlet开发步骤:

功能需求

  • 上述已经初步了解了Servlet的功能,动静网页以及和Servlet之间的关系,还有服务器以及服务器在开发工具中的使用。下面终于可以切入正题,怎么去写一个Servlet,或者说Servlet的开发步骤。当然我们想开发Servlet,首先得知道我要干什么,如果没有这个需求,硬开发一个对象,不知道干啥,这个就很奇怪了。所以,得规定一个要求,要求很简单,通过浏览器,去访问服务器,服务器是谁呢,当前用的服务器是谁呢,就是tomcat,我想通过浏览器,去访问服务器,8080,就访问到了,但我是希望更近一步,我要访问这个服务器中的一个项目,所以要写一个项目,希望访问到的这些项目,它给我返回一个东西,返回一个网页,希望网页上有什么呢,有这个服务器的,当前时间,希望服务器给我返回的网页上包含服务器的时间。

需求分析

  • 这个网页要求返回服务器时间,它给我返回时间,不同的人,不同的时刻去访问,这个时间会不一样,它是富有变化的,所以是动态的,再退一步讲,假设你说我搞个静态网页html,这个html我直接写好,放到服务器端,然后返回给浏览器,这个html上它怎么能出现服务器时间呢,你用js,new一个date,那个date是服务器时间么,不是,因为js,网页运行在浏览器上,得到的是浏览器时间,它可不是服务器时间 ,所以,你用html,有js,是搞不定的,说的是服务器时间,服务器时间必须由java来new,是java的时间,所以说,一定得用java来解决,因此呢,就是一个动态的东西,动态的网页。那动态网页用什么来做呢,就是Servlet,因为Servlet能拼动态网页。

需求设计

  • 那现在就要写一个Servlet对象,写这么一个类,通常这个类,我们一般什么作用,就叫什么什么Servlet,因为它的作用是输出一个时间,我给它起名叫TimeServlet,然后呢,这个类它是由Sun规定的,是有规则的,不是说你随便写一个就行,它有哪些规则呢,Sun要求,这个类,它必须实现一个接口,那个接口叫就叫做Servlet,你要实现这个接口,但是我们直接实现这个接口有点麻烦,因为这个接口中有好几个方法,Sun呢,也怕我们麻烦,于是呢,它给我们准备了一个默认的实现类,有一个默认实现类,叫什么呢,叫HttpServlet,就说是这样一个关系。Servlet是接口,HttpServlet是默认实现了这个接口,它就是一个实现类,是一个实现的关系,这HttpServlet这个类,实现了Servlet这个接口,那你看Sun要求我们实现Servlet这个接口,我们可不可以偷偷懒, 我就只继承于这个HttpServlet这个类,可不可以啊,可以,这样方便对吧,要不然你直接实现一个接口,写的东西太多,麻烦啊,所以我们可以呢,继承,用继承来解决问题,,我们可以这样继承,这样就省事了。但是你注意啊,我们平时说的话,说Servlet有什么要求,有什么规范,我们说的是,它要实现这个接口,我们说的话,是说它Servlet,但我们做的话,是继承它的子类,继承它的实现类HttpServlet,是这样的,就说和做是两码事。
  • 那我们写这个类TimeServlet,继承于这个父类HttpServlet,这个父类只是实现一些基本的逻辑,那我要干什么,它肯定不知道,我具体要干什么还得我自己实现,所以我需要重写父类的某一个方法,来解决问题,重新哪个方法呢,父类中有这样一个方法,叫做service() ,那么,我们需要呢,在TimeServlet这个子类当中,重写父类的这个方法,在这个方法里,我们写代码,给浏览器拼一个网页。那么,我们把这个类写完以后还不够,那我们写完一个对象以后,并不能在互联网上直接访问,要想能够访问到它,怎么办呢,需要加以注册,我们需要在一个配置文件里,对它注册,或说配置,那个配置文件叫什么呢,叫web.xml,我们需要呢,把这个对象,配置到,或者说注册到,这个文件里,注册好以后,那么它才在网上,有一个号,才能够加以访问,所以要进行配置。就是说,我们需要把这个对象配置到web.xml,这个文件里才可以。
  • 总体来讲,那么我们想开发一个Servlet,我们想开发这样的一个功能,那我们需要些什么呢,第一个,我要写这样一个类TimeServlet,而这个类的要求,要继承于它HttpServlet,这个关系搞清楚;第二点,我需要在web.xml配置文件里,配置TimeServlet这个类,即我们需要开发的这个地方,就两个地方,一个是写一个类,TimeServlet,第2个是配置,就完了,其实也没那么麻烦,挺容易。基本原则如下图:其中左侧是浏览器,右侧是服务器。
    在这里插入图片描述

需求实现

  • 任何一个web项目的需求设计,因为web项目调用流程,其本身步骤就很多,很繁琐,在加上复杂的业务需求,就更加复杂。所以,每一步的这个思路一定要保持清醒,清楚,那现在要做这个功能,非常的简单,就是我要访问服务器,服务器给我返回一个网页,页面上有个时间,但这个时间,它不是浏览器的时间,它是服务器时间,那服务器时间,就是我们需要用java去new一个Date,所以是动态的,如果写一个html的话,解决不了,就必须动态的拼,因为你写个对象才能拼java的东西,你写个html,html里没法直接写java,写不了,所以必须是动态的;再一个呢,从逻辑上讲,也说的通,我们每个人去访问这个服务器,得到的时间未必相同,时间是在不断变化的,每个人看到的有差别,不是100%都一样的。
  • 然后呢,那既然是动态的,所以我要写一个Servlet,因为它有能力拼动态的东西,然后呢,写的时候,Servlet这是一个组件,有规范,Sun的要求是实现Servlet这个接口,但它怕我们麻烦,给我们默认提供了一个默认的实现类,我们继承就好了;你注意HttpServlet,这个类不能直接用啊,你必须继承,它是很抽象的啊,你要继承,然后呢,重写某些方法,我们主要是重写service(),这个方法去拼东西,然后呢,还不够,还需要呢,加以配置才行。总之,一个小小的功能,它里面所包含的东西还挺多的,所以要搞清楚,需求设计分析完以后,开发时就很方便,没那么复杂。
创建项目
  • 首先第一步,先写一个类就可以了,先写TimeServlet这个类,当然,先写类之前,还得先建个项目做一些准备工作,打开Eclipse,先是创建web项目,在eclipse左边,右键,New Project,在弹出框里,选择谁呢,Maven Project:
    在这里插入图片描述
  • 选择Maven,有人说矛盾么,咱们现在不是写web项目么,这怎么是Maven项目呢,并不矛盾,web项目,表示的是我们的这个项目结构和思路,Maven项目指的是,我们这个项目要依赖于Maven插件,我们这个项目既是web项目,也是Maven项目,并不矛盾,所以,选择Maven项目,我们将来要用到Maven;然后下一步,勾选这句话Create a simple project:在这里插入图片描述
  • 再下一步,写组名,项目名,选择war包,Group Id: cn.cpy;Artifact Id:servlet1;Version:0.0.1-SNAPSHOT;Packaging:war;组名为公司的域名的倒写,项目名我叫,servlet1,第一个Servlet项目,然后选择war包,选择war包它才是web项目,最后完成,完成以后,等一会(下图项目名Artifact Id : servlet):
    在这里插入图片描述
  • 等一会以后,项目出来以后报叉,需要通过选中Deployment Descriptor : servlet1小地球,右键,选择Generate Deployment Descriptor Stub 之后,能去掉叉,那在点Generate,与不点的区别在于什么,没点Generate时,这个项目结果src/main/webapp下,是什么都没有的;点完以后,没叉了,但webapp下就有东西了,它多出了一个文件夹,WEB-INFO,大写的,WEB-INFO之下,有个配置文件,叫web.xml,这两个东西对web项目,是必要的,必须要有的,为什么之前会报错,就是因为这个项目中缺少了Web项目必须的东西,所以报错,我们点Generate的目的,就是为了生成它们俩,必须要有:在这里插入图片描述
    注:web项目中必须具备标准的目录结构,什么结构呢,就是,/src/webapp/WEB-INFO/web.xml,就这个目录,这个结构是标准的,web项目必须要有,没有就报错,那么这个web目录必须是这样的,如果说我不小心把web.xml给它删了,或者我把它挪到别地方了,就不对,不允许改动,WEB-INFO目录,也不允许改动,必须放到这,必须叫这个名字,这是固定的规则,一定要这样。
添加依赖
  • 那么创建完web项目以后, 第二步干什么呢,也不是立刻写代码,我们要继承于这个父类HttpServlet,从而间接的实现Servlet这个接口,但你会发现jdk,默认没有带这个东西,jdk没有Servlet这个接口这些内容,这些内容它不属于SE的内容,它不属于java自带的内容,它属于什么呢,它属于JavaEE,这个Java分好几部分, 什么javase,核心的API,基础的东西,还有JavaEE,面向企业的API,那这个内容,它属于面向企业的内容,面向企业的API, 是为企业,做web项目服务的,那这个内容我们要用的话,得单独导包,导入javaee的包,那么,导包的话,我们可以通过,Maven去导,通过Maven下载,打开一个浏览器,访问包服务器的网站,即maven服务器的那个网站。比如:阿里云的Maven服务器,在Maven服务器的网站上搜索依赖,那个我们需要导入的包,JavaEE的API,搜索javaee,选择如下:
    Group: javaee Artifact: javaee-api Version: 5,
    组名叫javaee,项目名也叫javaee-api,然后找到javaee-api-5.jar,这个jar包选中,将其出现如下的xml代码复制:
    ————————————————

    <dependency>
    ---- <groupId>javaee</groupId>
    ---- <artifactId>javaee-api</artifactId>
    ---- <version>5</version>
    </dependency>

    复制以后,再打开Eclipse的pom.xml文件,将其粘贴到其中的dependencies标签之下(如果没有此标签,自行添加),最后ctrl+s保存,这个Eclipse就会自动下载这个包了。这是第一种方式,但也可以不用这种方式,这种方式你了解下,也可以不用。

  • 还有第二种方式,第二种不用下载,比较快啊,一般用第二种,第二种方式是什么呢,这个Tomcat有能力运行有关Servlet这些个代码,那Tomcat内部是不是应该有这个javaee的包呢,javaee可以运行Servlet,它内部肯定得有这个包,是这意思,tomcat内部就有这个包,那这个tomcat已经在我们本地了,我们可以呢,直接依赖于tomcat的包,这样不用下载了,方便了,那怎么去依赖呢,也只有这个包能这么干,别的包不可以,就这一个可以,步骤如下:

  • 第一步,选择你的项目servlet1,右键,Properties,属性:
    在这里插入图片描述

  • 第二步,在弹出框里,选择Targeted Runtimes,右侧勾选,Apache Tomcat v7.0,打上勾,勾上的意思说什么呢,我这个项目,要依赖tomcat自带的包,要依赖它的包,这个包在本地,不用下载啊,勾上以后,点右下角,Apply,应用,就可以了,然后OK,关闭窗口就可以了:
    在这里插入图片描述

  • 那行不行呢,可以看一下,展开Java Resources/Libraries,这下面能不能看到Apache Tomcat v7.0,这个东西,能看到呢,表示说我依赖成功了,可以展开Apache Tomcat v7.0,看这里面有多少个包,一大堆,这个包存在哪,这个包存在了tts9之下,D:\tts9\apache-tomcat-7.0.67\lib下:
    在这里插入图片描述

  • 在那里存着呢,这里就有显示,那这里头哪个包是javaee呢,它不叫javaee,它叫什么呢,叫servlet-api.jar,这个其实就是javaee,就它,大概了解。
    在这里插入图片描述

  • 这个流程归纳一下是导入javaee的jar包的两种方式,第一种方式,就是Maven搜索,我们搜javaee这个单词,第二种方式是,这个依赖tomcat的包,怎么依赖呢,就是点击项目,就是右键项目,然后点,Properties,然后点,Targeted Runtimes,然后呢,勾选tomcat,然后呢,Apply,就可以了:
    在这里插入图片描述

代码解析
  • 开发一个Servlet的开发步骤,首先需要有一个功能需求,知道要做什么,然后分析这个需求,并设计这个需求的具体的实现思路,最后就根据这个设计思路,用代码去实现它,在写代码之前,首先需要创建一个web项目,之后添加javaee依赖包,建web项目时,需要注意的是,这个web项目有这个标准的目录结构,就需要通过那个动作,右键Generate,自动添加当前项目所缺少的目录及配置文件,/WEB-INF/web.xml;第二步在添加依赖,导包的话,这个有两种方式,一种是通过maven去搜,搜javaee,这个内容属于javaee的部分,企业级软件开发的部分,那么搜到一个以后可以用,这是第一种方式,但这种方式,毕竟我们是要从maven服务器下载这个包的,下载的话,网络不好,或者说哪有什么问题,失败了,失败的话,解决起来就麻烦,所以,只针对于javaee这个包,还可以用第二种方式,就是依赖tomcat的包,这种方式,对于别的包不行,只是对于javaee才可以 ,具体的步骤,选中项目右键,点Properties,弹出框里点targeted runtimes ,然后呢,勾选tomcat,apply,最后,你把这一步完成以后,要确认到底成没成功,在项目里面可以展开Libraries,甚至呢,展开这个Apache Tomcat,就能够看到,我们所导的那个tomcat内部的包,还挺多的,不用细看,然后,当然,那我们导的包,它存放在哪里,它是可以看出来的,这个包存放在哪里,能看出来,后面有路径,这是第二步导包。那么这种方式的话,不用下载,因为Tomcat已经在我们本地了,这样快一点,那这两步是这个准备工作,就完成了。

  • 那再进行下一步,下一步呢,就开始要写代码了,那么写代码呢,首先要写的是一个Servlet,它的名字叫TimeServlet,根据呢,它的功能给它命的名,一般什么功能,就叫什么名比较合理。那么,webapp下放的是网页,类要放到Java Resources之下,在Java Resources之下,它有4个目录,还有Libraries,Libraries是我们导的包存放在这里头了,除此以外,还有4个目录,

    src/main/java;
    src/main/resources;
    src/test/java;
    src/test/resources;

    其中,以test命名的包是测试,只是放测试案例,正式代码不要放这里来,那正式代码放main这里来,在这个main之下,有java,有resources,有什么区别呢,java之下,放java代码,resources下,放的是配置文件,比如properties文件。那现在要写这个类,这个类是正式的代码,那我们要把它放到src/main/java下,不要直接在这个目录下写类,这个类要有包,这是规则规矩(符合java访问权限的语法规则):
    在这里插入图片描述

  • 所以我们在这个src/main/java之下, 先建个包New,New什么呢,package,包名叫什么都行,看个人喜好,我喜欢叫web,当然工作时,它未必叫web,就是看个人喜好,叫什么都行,叫web:
    在这里插入图片描述
    在这里插入图片描述

  • 先建个包,因为我们当前所写的这个Servlet,它是web项目的一个核心的内容,解决的是web项目当中的这个关键的步骤,所以取名叫web,然后在这个包之下,再创建第一个Servlet,那这个类叫做TimeServlet,那这个类有要求,要求要继承于一个父类HttpServlet,从而间接的实现Servlet那个接口,那我们可以在这里,直接选中它的父类HttpServlet(也可以手写,就是说可以直接在类里extends谁谁谁,也可以):
    在这里插入图片描述
    在这个界面上,直接选择你要继承于谁,或者实现哪个接口,Name: TimeServlet,这是类名,这个Superclass,是父类,父类默认为java.lang.Object,Inferfaces,这是接口,默认没有实现任何接口,那想继承于谁,可以点Browse这个按钮改,想实现哪个接口,点Add这个按钮去加,可以在这里操作,那有人说,我手写不一样么,在这里操作有什么好处呢,是有好处的,我选择我要继承于这个父类,点Browse,Superclass后面的Browse按钮,它会弹出个框,这个框里可以搜一个类,那搜的时候,这个类的名字,我可以不用记完整,当然,现在要继承的父类名字很短,无所谓,比如说我要继承于SimpleDateFormat,假设比较长,搜sim*format,这可以这样搜,模糊查询,不用写完整就能搜到,这就是它的好处,想继承于谁,实现哪个接口的时候,不用把那个类名,接口名记完整,记一部分就行了,因为平时要写的代码,要用的类太多了,想都记住很困难,用这种方式搜,可以模糊搜索,比较方便:
    在这里插入图片描述

  • 那现在应该继承于HttpServlet,在这个结果当中,能看到这个类选择它,如果看不到这个类,证明什么问题呢,包没导成功,不过通过依赖Tomcat本身的javaee,这种情况导包,要是导不成功的话,这个不太可能,因为你tomcat就在你本地,你也选择了它,你都配好了,它肯定是能成功的,如果没成功的话,那就有点奇怪了,我倒是至今,倒是没遇到过这种情况。应都是可以的。选择HttpServlet,然后完成TimeServlet就继承了父类HttpServlet:
    在这里插入图片描述
    在这里插入图片描述

  • 继承于父类HttpServlet的TimeServlet类,有了以后,这个类要写什么呢,要重写父类的方法,父类是给我们实现了一定的逻辑,但它并不知道我们最终要干啥,所以这件事还得我们自己去写,那我们在这个父类的service()里重写,这是要求,这是规定,是Sun的要求;要重写父类的方法,怎么去重写父类的方法呢,不用手敲,右键可以选在这个TimeServlet类的内部空白区域,鼠标右键,然后,弹出框里选择Source,Source下面又有一堆选项,Source里面选择的是Override/Implement Methods…,点完以后,弹出个框对吧,这个框里,它给我们显示了3个类,一个类叫HttpServlet,是直接的父类,第二个叫GenericServlet,这个是HttpServlet的父亲,说白了,是我们当前这个TimeServlet类的爷爷,HttpServlet是父亲,这个GenericServlet是爷爷,Object呢,是当前TimeServlet类的太爷爷,它是按照辈分排的,逐渐向上的:
    在这里插入图片描述

  • 那我们现在要重写的方法在哪里呢,就在父类HttpServlet当中,我们展开这个父类,当然默认就展开,展开父类,它父类当中有很多方法,我们要写的方法叫service(),那你会发现,在后面有两个方法,都叫service,一个黄,一个绿,那我们要哪一个呢,看参数,它们的区别是不是就参数的区别,一个参数带Http,一个不带,那我们是带还是不带呢,带,因为Servlet是干什么的,它是动态拼网页,用术语讲,它是处理Http协议,它是和这个协议相关的,所以我们要的是,带Http这个字的,它才能够处理Http协议,勾选那个黄的service,勾上以后呢,OK,OK以后,Eclipse,它根据我们的选项,帮我们生成这个service()方法:
    在这里插入图片描述

    生成这个service方法以后,代码如下:

    package web;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class TimeServlet extends HttpServlet {
    
    	@Override
    	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		super.service(req, resp);
    	}
    }
    
  • 首先呢,这个方法内部的这个注释有用么,没有用,删掉,不删掉也行,但并不好,因为这个注释,它的意思TODO,是将来要实现,当前,不实现的意思,是待办的意思,如果你留着的话呢,将来会让人笑话,所以删掉,别让人笑话,还有super.service(arg0, arg1);,表示说如果父类的这个方法里有代码,我们要执行一下,那实际上,父类的这个方法里,确实有代码,那个代码,它强制抛了异常,为啥强制抛异常呢,说白了,因为它不知道这个业务该怎么实现,强制你来实现,怕你忘了,抛了个异常,所以怎么办呢,我们把这句话去掉,别调父类的代码,我们自己写,把这个service()方法内部清空,什么都没有,我们重新写;方法参数有两个,一个呢,叫HttpServletRequest arg0,一个叫HttpServletResponse arg1,我们平时简称叫,request,response,请求和响应;现在就要用到这两个参数名,看起来不舒服,改一下,arg0,arg1,这参数名别扭,不舒服,request,我把它就简写为req,response简写叫res,当然了,这个参数名无所谓,改成别的也行,不改也可以,这只是个人的习惯,不改也没关系,问题不大。

  • 那么现在我们要在这个方法内部,处理我们当前的逻辑,逻辑是什么,要求是,我们要给浏览器输出一个网页,这个网页之内要包含服务器时间,那首先我是不是得先有服务器时间,我先取到服务器时间,然后再拼这个网页,那第一步,就是准备这个数据,就是获取服务器的时间,所谓的获取服务器的时间,所指的是tomcat所在的,那台电脑的时间,它装在那台电脑的时间,那因为这个代码运行在tomcat里,这个代码是java代码,运行在tomcat里 ,而tomcat装在那台电脑上,运行时它读的是那台电脑的时间,是这样的。因为我们说服务器时间,指的就是服务器所在电脑的那个时间。

  • 那很容易,那就new一个Date就可以了,那就new Date,我们用的是java.util.Date,Date date = new Date();,引入的是java.util.Date, 那么,我们new的Date就是当前时间,那这个时间,它的格式不对,最好格式化一下,想格式化这个时间用谁呢,SimpleDateFormat,创建这个SimpleDateFormat,SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");,实例化SimpleDateFormat,指定格式,我只要时分秒,年月日我就不要了。那么,我们利用这个工具去格式化日期,那就得调它的方法,SimpleDateFormat点format,你把date日期传入,它会给你返回一个格式化以后的结果,是个字符串,String now = sdf.format(date);,这3句话是SE的内容。

  • 那我们得到服务器时间以后呢,下面做的一件事,就是要把这个时间拼到一个网页里,给浏览器返回,那不同的人访问服务器,我拼的时间就不同,就动态了(当然了,这个案例拼的是时间,那在其他的案例当中,可以拼,比如说,拼某个人的信息,拼某个人电话,拼这个任何的内容,你想拼什么都行,你就看你的业务了),接下来,将时间拼到一个网页里给浏览器返回,就把这个now拼到网页里,我们要拼一个网页,怎么拼呢,我们需要用到这个方法的第2个参数response,要用res这个东西,res.setContentType("text/html");,设置内容的类型,内容的类型是什么呢,text/html,这句话的意思是什么呢,告诉浏览器,我向你输出的是什么类型的东西,告诉它,我向你输出的是网页,不是别的,如果你不告诉浏览器,浏览器不知道你输出的是啥,如果它不知道会怎么办呢,它无法解析,它会让你保存这个文件,它认为是一个普通文件,特殊文件,让你保存,所以一定要写上这句话,写上这个类型,即告诉浏览器,向它发送的是什么类型的内容。那需要注意的是,在括号里写的是一个字符串,这个字符串是不能允许写成html/text的,这样颠倒过来是不允许的,颠倒了,或者你写错了都不行,差一个字都不行,这是规定,不能乱写。如果写错了,那么浏览器接收到内容以后,它一看是什么类型啊,不认识,不认识它一律会让你保存,所以如果一访问服务器,它让我保存,估计就可能是这写错了。

  • 那已经告诉它,我发送的是一个网页,然后呢,网页的内容是什么,我们要一句一句的输出,一句一句的拼,那怎么拼呢,PrintWriter w = res.getWriter();,我们通过response这个参数可以获取writer,得到的是PrintWriter,那这个PrintWriter是一个字符的输出流,我们向这个浏览器输出东西,输出的是网页,网页中不就是字符么,所以用字符流输出就可以了,Writer,那用这个Writer,我们可以一句一句的,往浏览器输出内容,就是获取输出流,该流指向的目标是浏览器。因为我们访问这个项目是,先访问服务器,访问服务器下的这个项目,那我们是访问服务器,服务器调了这段代码,所以,服务器它事先知道谁访问它,就哪个浏览器访问服务器,它是知道的,它知道你的IP,你的一切信息,然后呢,服务器会帮我们自动创建好这个流PrintWriter,我们拿来用就可以了,那res.getWriter()这个流,指向浏览器,是服务器做的,服务器干的,那有这流就好办了,我们就输出呗,那我们就动态拼一个网页。

  • 那动态拼网页,咱们就writer点println(),一行一行print就行了,那本来应该是怎样写啊,那我们要拼一个网页,应该把网页结构拼完整,按理来说我们应该这样拼呐,往println里拼,"<!doctype html>",然后再拼,再拼什么呢,再拼这个比如说html,html有开头,它还得有结尾,html里还得有head,head里还得有什么东西,

    w.println("<!doctype html>");
    w.println("<html>");
    w.println("<head>");
    w.println("</html>");

    一行一行拼呐,很累,太麻烦了,那这件事可以用jsp,会改善,会简化,但这里我就偷点懒,我就不写doctype,html,head了,那我写啥呢,我就直接写,咱们这个网页中,body中的那个内容,就我把head,body,这些标签都省略了,那你省略这个标签,这个还能显示对么,也可以,为啥呢,因为只输出一句话,没啥样式,所以浏览器都能识别,没关系,但这只是权宜之计,简单的案例这样凑合一下,还说的过去,如果是做正式的项目,真的是一个完整的网页,是万万不能这样写的,那为啥要偷懒呢 ,因为有改善的办法,用jsp时再写完整,现在的话,先偷个懒,此处偷懒,拼一个简化版的网页,仅此而已。

  • 那这个网页能简化到什么程度呢 ,就刚才我所说的,那罗里吧嗦的东西,全都省略了,我也不写什么head,也不写body了,我只写body中的内容,咱们的内容不就是,输出一句话,一个时间么,我希望呢,把这个时间啊,输出到段落里,所以,这里呢,我要向浏览器输出一个段落,一个p,那p里得有时间,所以我们还得在p里呢,拼上时间,w.println("<p>"+now+"</p>");,这就拼完了,当然了,我们现在是偷懒了。如果你想做淘宝啊,做京东啊,那样复杂的网页,假如说那个网页有2000行代码,你得print,2000次,很麻烦的,所以会有简化的方式,先这样吧。那拼完这个网页以后,最后别忘了,流是不是得关闭啊,哎,关闭流啊,w.close();,那这个类就写完了。

7.TimeServlet完整代码实现

package web;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.scenario.effect.impl.prism.PrImage;

public class TimeServlet extends HttpServlet {
	@Override
	protected void service(
			HttpServletRequest req, 
			HttpServletResponse res) throws ServletException, IOException {
		//获取服务器的时间
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String now = sdf.format(date);
		//将时间拼到一个网页里给浏览器返回
		//告诉浏览器向它发送的是什么类型的内容
		res.setContentType("text/html"); 
		//获取输出流,该流指向的目标是浏览器
		PrintWriter w = res.getWriter();
		//此处偷懒,拼一个简化不版的网页
		w.println("<p>"+now+"</p>");
		//关闭输出流
		w.close();	
	}
}

8.Servlet的难点解析

由上述代码就完成了一个简单的Servlet的开发,一共就7句话,前面3句话是JavaSE的内容,res.setContentType("text/html");这句话,也需要结合JavaSE的与IO相关的Writer使用,w.println("<p>"+now+"</p>");这句话拼网页是前端的内容,其实,都有关系,所以,为什么说Servlet 的内容,相对来说,稍微比以前难了,关键呢,主要是它的内容是依赖于以前的内容,它基于SE,基于前端,是基于那些东西的,所以呢,它是对Servlet以前的基础内容的一个综合,如果基础的内容有所忘记,就会对Servlet的理解有一定的影响,而基础的内容又特别的多,如果从头到尾复习的话,内容太多了,这是比较绝望的,一看就懵了,学习就是这样,需要不断的复习,不断的总结,理解,通过一个综合性的知识,将零散的知识连带起来,有个驱动力。

9.配置Servlet

  • Servlet类写完了,那还有一步,要配置它,在web.xml这个配置文件里配置它,web.xml这个文件,是在web项目中的一个核心的配置文件,很关键。打开这个web.xml配置文件,这是一个标准的xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    --<display-name>servlet1</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>
    </web-app>

    上来首先是版本,<?xml version="1.0" encoding="UTF-8"?>,然后是根元素,<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">,这个文件的根,叫web-app,web应用,根的下面自带一些内容,首先呢,是display-name标签,这个文件的显示名叫servlet1,跟项目同名,<display-name>servlet1</display-name>,这无所谓,其实删掉也没关系,留着吧;还有什么呢,welcome-file-list标签,欢迎页面,欢迎文件的列表,就是说,我们如果做一个网站的话,一般网站的首页,欢迎页,一般叫index.html,也可以简写啊,index.htm,它后缀写htm,也可以,也行,然后呢,还可以是jsp,index.jsp,也有的网站叫,default什么什么什么什么,这样的:

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

    那么,我们如果说,开发一个网站的话,这个首页是需要配的,我们一访问这个项目,它就立刻访问这个首页,是要配的,那么这个E clipse呢,怕我们配这个东西麻烦,它帮我们带上了,但其实呢,我们做的不是网站,我们做的是系统,做的是办公系统,所以呢,其实这个<welcome-file-list>...</welcome-file-list>没用,你留着也可以,不留着,删掉也没关系。那这个<welcome-file-list>...</welcome-file-list>,这个内容要用的话,怎么办呢,这个内容的应用,其实和网站的运营有关,所以如果现在不懂网站运营的话,可能理解不上去,也没关系,反正我们现在用不上,不管它了啊。然后呢,在这个内容之后,我要写新的内容,主要是要干什么呢,就是配置Servlet,那配置Servlet分为两步,这个是规定,就是这样,人家就这样设计的,你不要问我为啥,这是这个程序的设计者,这样设计的,他的规定。第一步我们要声明Servlet,并给它取个别名,别名就是小名,然后呢,还有第二步,第2步呢是通过别名引用这Servlet,并给它取个网名,给它取个网名,这个网名也可以叫,网络访问路径。

  • 先说第一步,别名部分写3个标签,互相嵌套,外面的标签叫servlet,表示我要配一个servlet,里边呢,有两个子标签,一个叫servlet-name,一个叫servlet-class:

    <servlet>
    --<servlet-name>time</servlet-name>
    --<servlet-class>web.TimeServlet</servlet-class>
    </servlet>

    写servlet-class标签时,可能会报错,是因为这个标签里面没写东西,缺少必要的内容,报错正常,写了内容就好了。那这个servlet-class里面写什么呢,写上我要声明的这个类的类名,这个写类名,写类名的时候,要把这个类名写完整,要带上包名, 包名加类名,完整,所以要写什么呢,web.TimeServlet,包名加类名写完整;那么如果我把这个类比做是一个人的话,那类名是这个人的大名,就正式的名字,是正经的名字,但是呢,我们在家里面内部的话,互相称呼的时候,可能会称呼小名,一个是比较亲切,一个是比较简短,比较这个舒服,servlet-name就是这个别名,这个小名,我们给这个类它取个别名,那别名叫啥呢,我叫time吧,那你注意体会这个别名的作用,别名是在家庭内部使用的,别人不知道,或者别人不了解,不熟悉,所以,我们写的这个time,是这个类的别名,是在哪里用的呢,是在当前的配置文件之内用的,如果这个文件的另外一个地方,也引用这个类,用别名servlet-name引用,而不是大名servlet-class,不是这个类名,类名太长,别名简短,所以,在当前的配置文件里,如果有别的地方要引用这个类,用别名引用,是这个意思。所以,别名的作用,是为了让这个文件里,引用它方便而这个声明的。

  • 第二步,网名部分,那么用户呢,想通过浏览器访问到这个类,这个类还必须得有个网名,因为它得在网络上访问,必须要有个网名,所以进行第2步,我们要给这个类,声明一个网名,网络访问路径,这个怎么写呢,这样写:

    <servlet-mapping>
    --<servlet-name>time</servlet-name>
    --<url-pattern>/ts</url-pattern>
    </servlet-mapping>

    总之,它的语法就是这样,没有任何疑问,就这样设计的,你就得这样写,servlet-mapping,mapping里面,有两个子标签,一个叫servlet-name,一个叫url-pattern,啊,那这个servlet-name,写的是什么呢,别名,因为这句话,主要是要给某一个servlet,声明网名,那到底是哪一个servlet呢,我要给它,web.TimeServlet声明网名,那我用别名time来引用它,所以servlet-mapping下的子标签servlet-name标签内部,这里面写的是什么呢,别名time<servlet-name>time</servlet-name>这句话是,通过别名time引用这个类web.TimeServlet类,然后呢,进而给这个web.TimeServlet类,取个网名,标签url-pattern这里面写的就是网名,网名能不能跟别名相同或者不同呢,可以相同,也可以不同,都可以,这里特意写成不同的啊,写什么呢,叫ts吧,前面得写上斜线,/ts,就是网名必须以斜线开头,这是要求。这就配完了这个Servlet,这段配置不用说非得理解,固定就这样写。

  • 概况而言,在web.xml中配置Servlet,它容易出错的地方,或者说,需要注意的地方,有3点,第一个是这个servlet-class,要保证类名不要写错,还要带上完整的包名,第二点,这个servlet和servlet-mapping,这两段标签的配置当中的servlet-name要一致,别名要一致,这有对应关系,第3点,这个网名需要以斜线开头,那么网名,可以与别名相同,也可以不同,如果说,那俩别名不一致,或者没有写斜线的话,那一启动Tomcat,直接就报错了,都不用访问就报错了,所以这个一定要注意,启动的时候,不要急着去访问,就是刚刚写完一段配置文件以后,启动时,最好呢,看一下控制台,报没报错, 因为如果说,这个配置文件写的有问题,一启动,就有可能报错,所以访问也没有用,看一下报没报错,实际上Tomcat在启动的时候,它会自动的读取这个web.xml配置文件,如果里面有语法错误,有问题,它会报错,你检查一下。

10.web.xml完整代码是实现

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>servlet1</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 -->
  <!-- 1.声明Servlet,并给它取个别名 -->
  <servlet>
  	<servlet-name>time</servlet-name>
  	<servlet-class>web.TimeServlet</servlet-class>
  </servlet>
  <!-- 2.通过别名引用Servlet,并给它取个网名(网络访问路径) -->
  <servlet-mapping>
  	<servlet-name>time</servlet-name>
  	<!-- 网名必须以/开头 -->
  	<url-pattern>/ts</url-pattern>
  </servlet-mapping>
</web-app>

11.项目部署与访问

项目部署

  • 这样就把这个Servlet全部开发完成了,概况一下,第一步先创建项目,第二步导包,导完完包以后,第3步就是,开发Servlet,主要是创建一个类,然后呢继承于HttpServlet,继承于它的目的是为了什么呢,间接实现了Servlet接口,这个接口,才是Sun公司的,最终的要求,我们是为了实现这个接口,然后呢,这个类要干什么呢,要重写谁呢,service(),在此方法内拼网页,这是开发这个Servlet,然后开发完以后,第4步我们是配置Servlet,怎么配置呢,就是在web.xml中,通过两步配置好这个类,两步,必须是这样。
  • 那配置完以后,Servlet这个代码就写完了,写完以后,现在直接访问它,还是访问不了,得怎么办呢,这个东西,TimeServlet类的项目,最终要存到服务器上,要存到Tomcat里,目前存进去了么,它并没有,目前这类存到哪去了呢,它存哪去了啊,它存在workspace里,不在Tomcat下,需要把它弄到Tomcat里,怎么弄过去呢,别手copy,手拷麻烦,因为拷过去以后,那个目录结构要有调整,不能手拷,手拷就会有问题,那我们用Eclipse去拷。那第5步,是部署项目,这一步叫部署项目。什么叫部署,部署是拷贝的术语,你可以说拷贝项目,不过显的很不专业,一般我们专业人士,聊天都是部署所以学会这个词,叫部署,那怎么部署呢,这个部署方式啊,有好几种,这里只说一种:
  • 首先打开Eclipse中这个Servers界面,选择Tomcat服务器,让服务器处于Stopped,没有启动的状态,选中它Tomcat,右键,Add and Remove...,增加或删除一个项目,就新部署或移除一个项目:
    在这里插入图片描述
  • 弹出一个框,里面有两个方块,左侧是待部署项目,未部署的项目,右侧是已部署的项目:
    在这里插入图片描述
  • 左侧选择,servlet1,点Add,把它挪到右侧,然后完成就可以了:
    在这里插入图片描述
  • 完成以后,Servers界面中的Tomcat左侧,有了个三角,能展开:
    在这里插入图片描述
  • 展开以后,能看到这个servlet1项目,表示Tomcat知道了这个项目要部署:
    在这里插入图片描述
  • 概括一下,打开Servers视图,选择Tomcat,右键Add and Remove,在弹出框内把左侧要部署的项目选中,添加到右侧,完成即可。到这为止,其实项目还没有部署,不信你可以打开Tomcat看,打开我的Tomcat,在tts9之下,那被部署的项目会放到哪去呢,那个项目会放到wtpwebapps下,最后一个路径下:
    在这里插入图片描述
  • 打开最后这个目录,并没有那个项目:
    在这里插入图片描述
  • 什么时候才会有,当我们启动时,新部署项目得启动一下,才会部署过去,选择Tomcat,点这个播放键,start,Tomcat启动了,这回再去看wtpwebapps那个目录下,就有这个项目了servlet1:
    在这里插入图片描述
  • 部署完以后再去打开Tomcat的这个wtpwebapps看现在这个项目servlet1,就有了,然后,打开部署好的这个项目,会发现它的结构和我们的原来的代码不一样,是有调整的:
    在这里插入图片描述

项目访问

  • Tomcat有了项目servlet1以后,就可以正式访问了,第6步,可以访问Servlet,怎么访问Servlet呢,我们写的路径这样写,http://localhost:8080,到这是访问 tomcat,那我们现在是要访问tomcat下面的项目,项目名叫什么呢,servlet1,它不就在tomcat之下么,所以下面写这个项目名,servlet1,然后呢,再斜线,写什么呢,servlet1里头有这个类名,有别名,有网名,访问时用哪一个呢,显然是网名,/ts,即http://localhost:8080/servlet1/ts,访问这个地址,如果看到了时间,就成功了,如果看到404,或者500,甚至405,则分别表示有不同的错误存在:
    在这里插入图片描述

项目再部署

  • 还有一点,如果在首次项目部署完成以后,当修改项目代码后需要重新部署,因为当修改后的代码写完以后,是不是那个tomcat下,还没有,如果改了代码以后,tomcat里是不是代码没更新呐,那怎么办呢,还得重新部署,怎么重新部署呢,把tomcat关了,然后呢,选中Servers视图下的Tomcat,右键,点这个publish,就不用点那个Add and Remove了,重新部署一下,就好了。什么叫重新部署,就是选择tomcat右键,publish,重新把这个项目再覆盖到tomcat里,另外,建议先关闭tomcat,再重新部署,再重启tomcat,建议按这个方式来做,这样比较好一点,有的时候,不这样做,会有问题:
    在这里插入图片描述
  • 另外如果代码修改之后,在重新部署之前,这个项目在Tomcat上标识是Republic:
    在这里插入图片描述
  • 在重新部署之后,这个项目在Tomcat上的标识,就变成了Synchronized,表示已同步,部署成功了:在这里插入图片描述
  • 最后需要注意的一点是,在修改项目代码时,服务器Tomcat最好处于关闭状态,如果你不关闭Tomcat的话,你一写,只要你一保存代码,这个代码会自动的部署一下,这样的话,你要是电脑性能不好的话,有点卡,所以最好是关掉Tomcat,然后修改,写代码,写完之后再重启,这样就会好一点,省着卡。

12.Servlet的执行过程及常见问题

  • 按照上面的预期做了一个小案例,小功能,就是想让服务器返回一个网页,页面上有个时间而已。当然了,网页越复杂,它拼的内容越多啊,可能就不止时间了,但是呢,基本的套路,都是这样的,写完以后发现,代码并不多,就是一个类,一个配置文件,代码没多少,但是一访问的话,很容易报错,那这个报错怎么解决,还是有一定的原则,有一定的规律,应该从什么角度去调试。如果只写一个类,或者只写一段js,写单个文件,还好调试错误,但写web项目,基本上都是写多个文件,一个复杂的web项目,想开发一个功能,可能是需要写好几个类,好几个配置文件,好多地方,那这些内容之间的衔接之处,它们之间的关系,要是搞不清楚的话,某一个环节写错了,那是死活也调不出来,所以理解这个案例,这段程序的执行过程,才能解决问题。
  • 这个项目其实很简单,就两部分代码,一部分呢,是类,一部分呢,是配置文件,那这两者到底是怎么执行的呢,由谁执行的呢,顺序是什么呢,关系是什么呢。那么这个项目是一个web项目,web项目,它得有浏览器,web项目,它也需要有服务器,这两者是缺一不可的。左边浏览器,右边服务器。那么代码是服务器端的,因为那个代码部署到服务器上了,它是由服务器运行的,当然,我们是通过浏览器访问的,但那段代码是由服务器运行的,首先是web.xml,然后是TimeServlet,里面有service方法,这个web.xml和这个类,它们之间的执行顺序是什么,彼此的关系又是什么,如下图:
    在这里插入图片描述
  • 我们整个项目是一个web项目,左侧是浏览器,右侧是服务器,然后呢,我们所运行的程序,无非就是两段代码,一段是web.xml当中的代码,一段是TimeServlet之中的代码,这两部分,那么这两部分代码的执行的顺序是什么,关系是什么,那整个程序是怎么去访问的呢,是由哪发起的访问呢,是我们在浏览器的地址栏输入一个地址,就发起了访问,正式的项目都是由浏览器发起的访问,敲地址访问,在地址栏输入了一系列的地址,比如/servlet1,然后/ts,即/servlet1/ts,敲完这个内容以后,一回车,就访问服务器了,服务器呢,就返回了东西了。那凭啥会这样呢,当我们在地址栏输入 地址以后,一回车,浏览器就会帮我们去访问服务器,浏览器就会向服务器发出一个请求,请求服务器给它返回一个网页来,那么请求达到服务器Tomcat以后,Tomcat会处理这个请求,那Tomcat也是一个软件,这个软件的内部有一个对象,这个对象,它能够处理这个请求,画个红色方块代表这个处理请求的对象,所以浏览器发出的请求最终提交给了tomcat这个软件之内的一个对象,这个对象要处理请求,首先呢,它会分析这个请求的路径,然后呢,做出一些处理,它怎么处理呢,这样的,就是Tomcat这个对象,第一件事,它会在tomcat下找名为servlet1的文件夹,因为它一看项目的访问路径,那它知道这个项目的路径的第一级,就/servlet1这一级,它知道是项目名,而这个项目名对应的是我们部署项目的一个文件夹,所以这个对象,它分析/sevrvlet1这一级路径,根据这一级路径上Tomcat上找,名为servlet1的文件夹,之前项目servlet1已经部署到了这个apache-tomcat-7.0.67/wtpwebapps下,是可以找到的;找到以后,它说啊,你要访问这个项目,那你要访问这个项目下的谁呢,那它还会做下一步操作,那下一步干什么呢,这个对象,它会在此文件夹下找到谁呢,web.xml,它下一步是直接去找web.xml,那这个servlet1文件夹里有web.xml么,我打开apache-tomcat-7.0.67/wtpwebapps/servlet1/WEB-INFWEB-INF下是有的,总之,它在这个目录下,一定能找到这个东西,任何web项目都会有这个东西,一定会找到的,这是第二步。
  • 那第二步呢,就是说,这个tomcat服务器,它里面有个对象,这个对象它去分析了我们的访问路径,然后呢,它通过访问路径去找到我们要访问的那个文件夹,然后呢,在文件夹之下,找到了web.xml,这是第二步,那第二步找到了这个这个文件夹以后,然后怎么办呢,那它知道我们是要得到一个网页,那你想访问谁得到网页呢,它再分析路径一看啊,你这里写的是/ts,你写的是/servlet1/ts,这个目录上,那tomcat知道了你要找网名为/ts的那个东西,所以呢,下一步,第三步,tomcat中的这个对象,它就会在web.xml里找/ts,因为url-pattern标签里写了/ts,它会去找/ts,只要没写错,就能找到,所以第三步,是在配置文件里找这个网名,找到网名以后,它一看啊,你要调这个东西,那根据网名,能否知道,对应的别名servlet-name呢,可以的,根据别名能否知道对应的类名servlet-class呢,所以,根据网名可以得到别名,而最后根据别名又能够知道类名,而最终目的就是想调这个TimeServlet类。所以,tomcat经过一系列的折腾,最终根据这个路径/servlet1/ts,找到了这个类,那我们写的路径,其实目的是什么呢,是要找到这个类,怎么找由tomcat来找,通过对应关系来找,是这样的一个关系。
  • 那这个找的过程里面,路径里写的/ts,和url-pattern对应,路径里写的/servlet1,和项目名对应,然后呢,web.xml中写的这个别名servlet-name,和servlet标签和servlet-mapping标签,前后也对应, 最终,经过一系列动作,我们找到了这个类名TimeServlet,这是我要的最终的目标,那找到这个类名以后,这个类由谁来调用呢,Tomcat,咱们没有自己去实例化它吧,我们没有去调它吧,没有,那在正式的web项目下,程序是由服务器去调用的,不是我们去调用的,那么tomcat千辛万苦终于找到这个类,它帮我们去调,怎么调呢,它会两步,第一步,它会帮我们实例化这个类,它会new它,new这个类,得到一个对象,new完以后,就调这个对象的service方法,所以,它两步,先new,new完以后,再调这个service方法。
  • 至此程序由第一步发出请求给服务器 ,第二步服务器根据访问路径找到了这个目录,找到了web.xml,然后呢,第3步,在web.xml里找到了这个网名,根据别名找到类名,找到以后,实例化这个类,调它的service方法,那这个类,它一定会有service方法么,一定会有的,因为在写servlet时,要求要继承于父类,要写service这个方法,如果你没写,那是你的问题,你程序员连这个都不写,那你就有责任了,你一定要写,一定会有的。所以就可以调这个方法,那这是第4步,最后,实例化,并调这个对象,第5步,调完以后,那这个service里面代的码是print,所以呢,这个服务器调了这段代码,向浏览器print了一些东西,浏览器得到了这个输出的东西,是这么一个流程。
  • 由上述的分析,尽管我们在写程序时,先写类,后写配置文件,但是呢,调用时是反过来的。那么在地址栏写的项目名,得和服务器tomcat里的项目名对应上,如果你地址栏项目名写错了,找不到我们地址栏写的网名,如果网名和这个配置文件不对应,写错了,就找不到,那还有在web.xml配置文件中,servlet-name里的别名time不一致,也肯定找不到,如果说,这些地方没有对应,写错了,不管是什么原因,都找不到,找不到的话,我们会得到这样一个错误,404,404就是找不到资源,找不到这个东西,所以,如果程序报了404的错误,需要从图中标颜色的这些地方,看看地址栏的黄色部分和项目名对不对应,绿色和网名对不对应,配置文件里的两个别名对不对应,都得对应,才能够不404,否则就是404,这是404的问题。
  • 还有一种情况,这个servlet-class对应的类的类名写错了,也有可能,如果类名写错了,或者是这个类的service方法内部有什么语法错误,有什么错误,那么我们会得到这样的一个提示,500,500表示什么意思呢,第一种情况是类名写错,就是500,第2种情况是方法内有错误,也是500,所以,两种原因都可能导致500,所以出现500的话,检查什么呢,这个类的名字的声明,<servlet-class>web.TimeServlet</servlet-class>,和开发时所写的类对不对应,或者方法内有误也是500。
  • 如果你出现405这个问题,出现405要深刻反省下,这个不可原谅,什么叫405呢,是方法声明有误,什么叫方法声明有误,比如说,这个方法本来是没有返回值,你写了返回值,本来是俩参数,写了3个参数,这叫声明有误,这个方法都是自动生成的,还能有误,那都什么情况,这是不可原谅的。
  • 那还有一个问题是直接访问tomcat时,就没部署项目,直接访问tomcat,一点问题没有,部署完项目以后,一启动,就有问题,就访问不了,就有问题,然后呢,仔细检查,这个项目也没有错,然后呢,Eclipse重启以后,就好了,这个问题有可能是写完的代码,没有编译,怎么去确认代码有没有编译呢,打开tomcat,看wtpwebapps目录下这个项目,再打开WEB-INF这个目录,看一看有没有classes目录,然后呢,看一看classes之下有没有那个TimeServlet类,如果说这里面没有这个类,就表明这个代码没有被编译,是编译的问题,可能会是这样的问题。那是编译的问题怎么解决呢,就是在Eclipse上方有一个选项叫Project,里面有`Build Automatically,要把它勾选,如果没勾上,它不会自动编译,可能会导致有问题,但你重启时,它就会编译。
    在这里插入图片描述
  • 最后,还可能有一个问题,如果这个tomcat里没有wtpwebapps那个目录,为啥没有呢,就是在配置tomcat时,最后一步你忘做,配置完Tomcat,最后一步是什么呢,是打开Servers视图,双击Tomcat,在弹出的窗口OverviewServer Locations这个地方,勾选第二个选项Use Tomcat installation(takes control of Tomcat installation),你不勾选,就不会有那个wtpwebapps目录,那个项目不知道被放哪里去了,被放到一个很很隐蔽的目录下,你是找不着的,就会有困扰,所以一定要勾选,但是呢,之前你没勾选的话,可能有的时候,还勾选不上了,那很悲催啊,怎么办呢,重配一遍Tomcat,谁让你一开始,没勾选呢,是吧,重勾一遍啊,这个地方:
    在这里插入图片描述
  • 类似案例练习:创建RandomServlet,然后,向浏览器拼一个网页,网页内包含一个随机数。

参考文献(References)

文中如有侵权行为,请联系me。。。。。。。。。。。。。
文中的错误,理解不到位的地方在所难免,也请指教!在成长过程中,也将继续不断完善,不作为专业文章。不喜勿喷。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值