1.servlet是什么?

servlet的本质是接口,接口就是一种规范。我们来看一下servlet接口中都有哪些函数:



图片来源:https://www.cnblogs.com/whgk/p/6399262.html

看上去很简单,servlet上只有五个函数的接口。其中init、service和destroy是与servlet生命周期相关的三个函数:

服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)方法

该servlet对象去处理所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行

最后服务器关闭时,才会销毁这个servlet对象,执行destroy()方法。

getServletConfig()方法来获取ServletConfig对象(注意ServletConfig也是一种接口),通过ServletConfig对象可以获取到Servlet的一些信息,ServletName、ServletContext、InitParameter、InitParameterNames等。这里要重点看一下ServletContext,它的本质是一种容器,可以看成map。可以在整个web应用的动态资源(servlet/jsp)之间共享数据。


2.我们作为web层的开发者,直接去实现servlet接口来开发吗?

显然不会这样做。servlet接口过于简单抽象,与真正的开发实践还是又一段距离的。所幸有GenericServlet类

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216145502191-411577839.png

我们可以发现,init方法有两个,一个是带有参数ServletConfig的,一个有无参的方法,为什么这样设计?这里需要知道其中做了什么事情,来看看这两个方法分别做了什么事?

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216145829785-244456335.png

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216145902488-312998049.png

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216145934441-854020880.png

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216150037300-348044601.png

init(ServletConfig config)方法,因为只有init(ServletConfig config)中带有ServletConfig对象,为了方便能够在其他地方也能直接使用ServletConfig对象,而不仅仅局限在init(ServletConfig config)方法中,所以创建一个私有的成员变量config,在init(ServletConfig config)方法中就将其赋值给config,然后通过getServletConfig()方法就能够获取ServletConfig对象了,这个可以理解,但是在init(ServletConfig config)中,158行,还调用了一个init()方法,并且这个init()方法是空的,什么读没有,这是为什么呢?这个原因是为了防止一件事情,当我们需要在init方法中做一点别的事情,我们想到的方法就是继承GenericServlet并且重写了init(ServletConfig config)方法,这样依赖,就破坏了原本在GenericServlet类中init(ServletConfig config)写的代码了,也就是在GenericServlet类中的成员变量config会一直是null,无法得到赋值,因为被重写了,就不会在执行GenericServlet中init(ServletConfig config)方法中的代码。要想赋值,就必须在重写的init(ServletConfig config)方法中调用父类的init(ServletConfig config)方法,也就是super.init(ServletConfig config),这样一来,就很不方便,怕有时候会忘了写这句代码,所以在GenericServlet类中增加一个init()方法,以后需要在init方法中需要初始化别的数据,只需要重写init()这个方法,而不需要去覆盖init(ServletConfig config)这个方法,这样设计,就好很多,不用在管init(ServletConfig config)这个其中的内容了。也不用出现其他的问题。

但是GenericServlet类并没有实现service方法,而是由HttpServlet类继承并实现了这一方法。

图片来源:https://images2015.cnblogs.com/blog/874710/201702/874710-20170216152409566-1602415910.png

该方法中就做一件事情,就是将ServletRequest和ServletResponse这两个对象强转为HttpServletRequest和HttpServletResponse对象。为什么能这样转?

首先要知道req、res是什么类型,通过打印System.out.println(req),可以知道,req实际上的类型是org.apache.catalina.connector.RequestFacade 

RequestFacade实现了HttpServlet, HttpServlet又继承了ServletRequest接口。因此,req即可以被当做ServletRequest出现在函数的形参中,又可以被强制类型转换成HttpServlet。究其本质,是面向对象编程的多态性。

service(HttpServletRequest req, HttpServletResponse resp)

这个方法就是判断浏览器过来的请求方式是哪种,每种的处理方式不一样,我们常用的就是get,post,并且,我们处理的方式可能有很多的内容,所以,在该方法内会将get,post等其他5种请求方式提取出来,变成单个的方法,然后我们需要编写servlet时,就可以直接重写doGet或者doPost方法就行了,而不是重写service方法,更加有针对性。所以这里就回到了我们上面编写servlet时的情况,继承httpServlet,而只要重写两个方法,一个doGet,一个doPost,其实就是service方法会调用这两个方法中的一个(看请求方式)。

最新文章

  1. AEAI DP V3.7.0 发布,开源综合应用开发平台
  2. 解决ScrollView 嵌套 GridView 单行显示问题
  3. error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
  4. Fatal error: Allowed memory size of 524288000 bytes exhausted (tried to allocate 64 bytes) in D
  5. Mybatis入门例子
  6. 转载jQuery图片放大插件[twiPicZoom]
  7. SQLite 批量insert - 如何加速SQLite的插入操作
  8. 使用python远程登录
  9. Android ListView无法触发ItemClick事件
  10. 设置sudo不输入密码 sudoers 编辑出错后的补救方法
  11. oracle时间格式转换问题 ORA-01810: format code appears twice--转
  12. arrayPointer
  13. Extjs 6 MVC开发模式(二)
  14. Ext JS4百强应用: 做可编辑的,可checked的treegrid--第11强
  15. Wincc flexable的局势视图的组态
  16. Python:猜拳游戏
  17. 微信小程序 + mock.js 实现后台模拟及调试
  18. Python 字典和集合基于哈希表实现
  19. Hibernate框架笔记01_环境搭建_API_CRUD
  20. Docker Kubernetes Service 网络服务代理模式详解

热门文章

  1. Iperius Backup Full--小中企业简单自动备份的实用工具
  2. day82:luffy:课程详情页面显示&章节和课时显示&视频播放组件&CKEditor富文本编辑器
  3. C语言100题集合005-删除一维数组中所有相同的数,使之只剩一个
  4. Round 4
  5. .net 实现 一二级分类
  6. 分布式文档存储数据库之MongoDB副本集
  7. Android基础——项目的文件结构(一)
  8. Delphi ADO更新条件
  9. Mybatis执行SQL的流程
  10. 1、线性DP 354. 俄罗斯套娃信封问题