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. 什么PO模式?

    PO模式PO是Page Object的缩写,PO模式是自动化测试项目开发实践的最佳设计模式之一.核心思想是通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化, 只需要调整页面元素封 ...

  2. C# stopwatch的简单使用(计算程序执行时间)

    首先添加引用 using System.Diagnostics;//stopwatch的引用 //声明变量 Stopwatch a=new Stopwatch();//PS:这里一定要new(实例化) ...

  3. python中的evalexec 将字符串当做代码执行

    eval/exec 将字符串当做代码执行 eval/exec 这两个函数可以将字符串解析为代码并执行. 区别 1.eval 解析变量和表达式, 而 exec 解析语句 a = '1' print(ev ...

  4. win10右键打开PowerShell

    win10右键打开PowerShell 转载自:http://www.xitongzhijia.net/xtjc/20170526/98756.html 如图: 1.首先在桌面新建一个txt文文件 复 ...

  5. html关键字高亮

    /** * @id 父节点id * @key 关键字 */ function keyLight(id, key, bgColor){ var oDiv = document.getElementByI ...

  6. zookeeper单机/集群安装和使用

    简书原文地址:https://www.jianshu.com/p/88194fde9a07 或者关注我的公众号"进阶者euj" 前提是本机有jdk 一.单机安装 1.去官网下载zo ...

  7. ArrayList使用及原理

    之前面试时,经常被问到ArrayList的原理,今天整理了一些ArrayList的使用原理和必问的知识点. ArrayList的继承关系 定义一个ArrayList的方法 ArrayList的三个构造 ...

  8. 第05组 Alpha冲刺(4/6)

    .th1 { font-family: 黑体; font-size: 25px; color: rgba(0, 0, 255, 1) } #ka { margin-top: 50px } .aaa11 ...

  9. 4. 树形DP

    337. 打家劫舍 III https://leetcode-cn.com/problems/house-robber-iii/ /** * Definition for a binary tree ...

  10. InnoDB Insert Buffer(插入缓冲 转)

    一,插入缓冲(Insert Buffer/Change Buffer):提升插入性能 只对于非聚集索引(非唯一)的插入和更新有效,对于每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓 ...