Java servlet service方法 源码深入解析 接收浏览器请求流程

1.servlet的存在意义

	1.servlet的实现遵循了服务器能够识别的规则,也就是服务器会自动根据请求调用对应的servlet方法进行处理
	2.狭义的servlet是指java实现的一个接口,广义的servlet是实现了这个servlet接口的类
	3.servlet运行在支持java的应用服务器上
	4.tomcat服务器上的运行流程:浏览器发送请求到服务器,服务器根据请求url在webapps目录下找到对应的项目文件夹
      然后在web.xml中检索对应的servlet,找到后调用执行servlet

2.service方法的剖析

1.服务器调用相应servlet,实际上是调用相应的service方法
2.定义service方法的顶层接口是Servlet:
Servlet接口源码图

注意:该service方法中传递的是ServletRequest和ServletResponse参数

3.我们需要关心的实现类是HttpServlet:
在这里插入图片描述

注意:
1.我们可以看到HttpServlet抽象类中有两个service方法
2.public修饰的service方法是上面继承下来的
3.protected修饰的service方法是该抽象类中实现的重载方法,其参数已经变成了HttpServletRequest和HttpServletResponse,即标准化到了HTTP协议类型参数

4.HttpServlet中的public void service 方法源码:
在这里插入图片描述

注意:
1.可以看到,该service方法将参数强制转化为Http协议标准的参数,捕获类型转化错误异常,其实该方法是当时的设计人员认为未来的协议可能不止是Http协议一种,因此有了这个操作
2.强转参数后,再调用本类的另一个service方法,即protected修饰的service方法

5.protected void service 方法源码:
在这里插入图片描述

注意:
该service方法是处理各种请求方式的,先匹配相应请求方法,再调用本类中的doGet、doPost等对应方法

6.再来看下HttpServlet中的相应请求方法源码:
在这里插入图片描述

注意:
1.可以看到,请求方法中没有对数据的处理逻辑,只会抛出405和400错误
2.405错误:子类中没有重写doGet等对应的请求方法,但调用了父类的service方法,即找不到相应的请求方法
3.400错误:Http协议请求错误

3.service方法的调用

1.继承HttpServlet的类就是我们实际编写的servlet类,当服务器由url-pattern调用该servlet类时,根据该类中重写的方法会有以下几种情况的方法调用:

1.只重写了service方法:
服务器的各种请求都会调用这个service方法
2.重写了service方法,还重写了doGet或doPost方法,但没在service方法中调用父类的service方法(即super.service(req,resp)):
服务器各种请求只会调用该service方法,不会调用重写的doGet和doPost方法
3.重写了service方法、doGet或doPost方法,且在service方法中调用了父类的service方法:
服务器会调用重写的service方法和根据请求类型调用重写的doGet或doPost方法,如果没有重写doGet或doPost方法会报405错误
4.没有重写service方法,但重写了doGet和doPost方法:
根据请求类型直接调用重写的doGet或doPost方法

2.上述情况的原理分析:
首先,我们应知道,服务器调用我们所写的servlet所传参数是服务器自己实现的,即:

ServletRequest:封装了请求信息,可以从中获取到任何的请求信息。
ServletResponse:封装了响应信息,用于响应用户请求。

这两个接口都是服务器给予实现的,并在服务器调用service方法时传入。对,服务器进入servlet不会找其他方法,只会找service方法而且是实现了Servlet顶层接口的实现类的service方法,即HttpServlet抽象类中参数为ServletRequest和ServletResponse的service方法,但在我们所写的servlet中找不到该service方法,那么就去他的父类中找,即HttpServet类,找到该方法后调用,其内部将服务器传过来的ServletRequest和ServletResponse参数强转为Http标准的参数类型,再调用另一个重载的service方法(即参数为HttpServletRequest和HttpServletResponse的service方法),但根据多态调用,如果我们所写的servlet中重写了service方法,那么刚才调用的就不是HttpServlet中的service方法,而是子类中重写的service方法,同理,如果子类重写了doGet或doPost方法,那么调用的就不是HttpServlet中的doGet或doPost方法,而是子类重写的方法。

这里简单说下上面几种情况的运行过程,为了方便,我将HttpServlet抽象类中实现了Servlet顶层接口的service方法称为service01,将HttpServlet抽象类中重载的service方法称为service02,子类重写的方法后加@Override:

1.service01–>service02(@Override)
2.service01–>service02(@Override)
3.service01–>service02(@Override)–>service02–>doGet/doPost(@Override)
4.service01–>service02–>doGet/doPost(@Override)

总结

由上我们可以知道,浏览器访问服务器,找的是service方法,而且是Servlet接口中的service方法,因此servlet要想被浏览器请求到,必须直接或间接的实现Servlet接口(我们编写的servlet是间接实现Servlet接口的)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值