本文主要是介绍HttpServlet背后的那些事!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
阅读本篇文章大约花费您4分钟!
我们自己新建一个Servlet类的时候,我们通常会继承自HttpServlet类,并且编译器也是默认帮我们继承了HttpServlet类,为什么我们要继承HttpSerlvet类呢?初学Web的同学一定知道Servlet类,并且熟知里面的五个方法和Serlvet的生命周期,为什么到具体使用Serlvet的时候却和HttpServlet关系深厚,看起来和Serlvet类好像没什么关系?
今天我们就来看一下这其中到底是怎么回事。我们需要了解三个类,分别是Servlet,GenericServlet,HttpServlet。
Servlet接口
Servlet中一共有五个方法,其中包含三个生命周期方法:
- init(ServletConfig config) 初始化方法【生命周期方法】
- service()方法 具体的操作方法 【生命周期方法】
- destroy()方法 销毁方法 【生命周期方法】
- getServletInfo() 返回Serlvet描述信息 【非生命周期方法】
- getServletConfig() 返回servlet配置对象 【非生命周期方法】
实现serlvet接口我们必须重写这五个方法,显然这是不友好的,所以有一个GenericServlet类对Servlet进行了封装。
GenericServlet类
GenericServlet类是一个抽象类,实现Servlet接口,其中主要完成了以下工作:
- 将init(ServletConfig config)方法中的config对象赋给类的成员变量,可以通过getServletConfig()获得
- 为Servlet接口所有方法提供默认的实现(有的是空方法体)
- 提供一个新的不带参数的init()方法,子类通过重写这个方法而不是原始的init()方法来进行初始化工作
大致的实现代码如下:
abstract class GenericServlet implements Servlet,ServletConfig{private ServletConfig servletConfig;public void init(ServletConfig servletConfig) throws ServletException {this.servletConfig=servletConfig;//调用自定义的init() this.init();}//自定义的init()方法,可以由子类覆盖public void init(){ }//实现service()空方法,并且声明为抽象方法,强制子类必须实现service()方法 public abstract void service(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOException{}//实现空的destroy方法public void destroy(){ }}
自定义init()方法的原因是:如果子类要初始化必须覆盖父类的init(ServletConfig)而使它无效, this.servletConfig=servletConfig不起作用 这样就会导致空指针异常。自定义init()后,如果子类要初始化,可以直接覆盖不带参数的init()方法。
不该参数的init()方法不是生命周期方法。
进行了这样的封装,一个Servlet继承自GenericServlet要方便很多,但是在网络应用中,离不开Http协议,而GenericServlet中的方法还很少,无法满足我们的使用,于是出现了HttpServlet。
HttpServlet类
HttpServlet是一个抽象类,进一步继承了GenericServlet。它不仅进一步封装了Serlvet,还提供了很大Http相关的方法,关于这些方法的使用都很简单,这里不再赘述,主要看一下HttpServlet是如何改进GenericServlet的。
在HttpServlet中,主要做了如下两个改动:
- 重写原始service()方法,并且重新定义了一个service(HttpServletRequest req,HttpServletResponse res),注意这里的两个参数变了,HttpServletRequest是ServletRequest的子类,封装了Http相关内容,HttpServletResponse也是一样。
- 在自定义的service()方法中,针对不同的请求分别调用处理不同请求的方法doGet(),doPost()
代码如下:
abstract class HttpServlet extends GenericServlet{//HttpServlet中的serviceprotected void service(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){//该方法通过httpServletRequest.getMethod()判断请求类型调用doGet() doPost()}//必须实现父类的service()方法public void service(ServletRequest servletRequest,ServletResponse servletResponse){HttpServletRequest request;HttpServletResponse response;//由于HttpSerlvetRequest/response是ServletRequest/response的子类,可以转换try{request=(HttpServletRequest)servletRequest;response=(HttpServletResponse)servletResponse;}catch(ClassCastException){throw new ServletException("non-http request or response");}//调用service()方法this.service(request,response);}}
经过HttpSerlvet封装之后,我们只需要针对不同的请求重写doPost()或者doGet()方法即可,也就是我们平时在eclipse中最常使用的方式。
这就是Servlet到HttpServlet的过程,了解了这个过程有助于帮助Serlvet的理解,平时在学习的时候,也应该从底层原理取理解一项技术,这样不仅能帮助我们理解,也可以学习到很多优秀的编程思想,这也是大家都建议程序员要学会阅读源码的原因之一。
希望大家都可以在自己的道路上闯出一片天地!
这篇关于HttpServlet背后的那些事!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!