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方法会调用这两个方法中的一个(看请求方式)。

浅谈JAVA servlet的更多相关文章

  1. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

  2. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  3. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  4. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  5. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  6. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  7. 浅谈java性能分析

    浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...

  8. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  9. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

随机推荐

  1. python中的类方法,实例方法和静态方法的区别

    类方法是类的方法,在定义的时候要在上方加上一个@classmethod装饰器来进行装饰,形参是cls,类和实例都可以取调用类方法: 实例方法是实例对象方法,只有实例可以调用,类是不能调用的,形参是se ...

  2. Windows Server 2019 在桌面图标

    直接按Win(键盘上的微软徽标键)+R,输入: rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0 回车 rundll32.exe shell32. ...

  3. Socket创建简单服务器和客户端程序

    使用Socket编程创建简单服务器和客户端 要知道的 Socket-AddressFamily, SocketType, ProtocolType https://blog.csdn.net/weix ...

  4. UOJ Round总结

    #22. [UR #1]外星人 一开始随便搞出第一问答案,很显然的性质对$x$有变化的$a$一定是递减的,就拿一个桶直接记录可以达到的值 然后我开始想第二问,一开始想直接在这个桶上统计答案,然后发现不 ...

  5. 2.1获取Git仓库-2.2记录每次更新到仓库

    2.1 获取 Git 仓库 获取 Git 仓库通常有两种方式 将尚未进行版本控制的本地目录转换为 Git 仓库: 从其它服务器 克隆 一个已存在的 Git 仓库. 在已存在目录中初始化仓库 首先进入该 ...

  6. JS数组去重的9种方法(包括去重NaN和复杂数组类型)

    其实网上已经有很多js数组的去重方法,但是我看了很多篇并自己通过代码验证,发现都有一些缺陷,于是在研究多篇代码之后,自己总结了9种方法,如果有哪里不对请及时纠正我哈~ 转载请表明出处 测试代码 let ...

  7. [MIT6.006] 4. Heaps and Heap Sort 堆,堆排序

    第4节课仍然是讲排序,但介绍的是一种很高效的堆排序. 在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除.而排序问题也可以看作是一个extra ...

  8. MongoDB基础教程(安装、操作、配置)

    MongoDB 下载安装 简易安装 # redhat, centOS sudo yum install -y mongodb # debian, ubuntu sudo apt install -y ...

  9. socket里面那个又爱又恨的锁

    查一个问题:结果看了一下软中断以及系统 所耗cpu,心中满是伤痕啊------- perf 结果一眼可以看到:主要是锁 那么这个lock 是用来干什么的呢?? A:TCP socket的使用者有两种: ...

  10. 机器学习3《数据集与k-近邻算法》

    机器学习数据类型: ●离散型数据:由记录不同类别个体的数目所得到的数据,又称计数数据,所 有这些数据全部都是整数,而且不能再细分,也不能进一步提高他们的精确度. ●连续型数据:交量可以在某个范围内取任 ...