博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
理解HttpServlet抽象类没有抽象方法(从Servlet--GenericServlet--HttpServlet)
阅读量:6516 次
发布时间:2019-06-24

本文共 5320 字,大约阅读时间需要 17 分钟。

理解HttpServlet抽象类没有抽象方法

前两天复习了下Servlet,查看源码的时候发现了一个问题:HttpServlet已经实现了父类的所有抽象方法,为什么被定义成一个抽象类呢?想了好一阵。为了好理解我们就从Servlet–>GenericServlet–>HttpServlet一步步来看(顺便复习下Servlet)

1.Servlet

要新建一个servlet就要实现Servlet接口,我们来看Servlet接口里面的方法

在这里插入图片描述

①init(ServletConfig)当servlet类被加载时servlet容器会先调用servlet的空参构造器,然后调用init()方法并传入(ServletConfig(代表当前servlet的一些配置信息))
②getServletConfi()可以通过此方法获得ServletConfig
③ service(ServletRequest,ServletResponse)当有请求该servlet时,会调用该方法
④destroy 当卸载当前servlet容器时调用该方法销毁servlet

2.ServletConfi

可以看一下ServletConfig这个接口

在这里插入图片描述

①getServletName() 方法是可以返回当前servlet的名字(也就是web.xml文件中标签中中的值)
②getServletContext ()方法是返回ServletContext(当前web应用的上下文(每个web应用对应一个ServletContext,定义了servlet用来与servlet容器通信的多种方法))
③getInitParameter(string) 该方法可以根据名字来获取servlet的初始化参数
④getInitParameterNames ()该方法用来获取出初始化参数的参数名,注意返回类型为Enumeration 类型

每次要新建一个servlet都要实现Servlet接口(ServletConfig接口可不实现,因为ServletContext可以通过servletConfig.getServletContext()方法获得,前文提到ServletConfig接口是因为下面的GenericServlet要用到)重写这好几个方法是不是太麻烦好的,GenericServlet抽象类出现了

3.GenericServlet

该类实现了Servlet, ServletConfig接口并重写了方法,大家可自行查看源码,GenericServlet抽象类实现了上面讲到的两个接口的,所以很多方法不在赘述。我们来看其方法

在这里插入图片描述

①service(ServletRequest,ServletRespone) 该方法是servlet继承该抽象类后要实现的抽象方法,还是当请求该servlet时会调用该方法。、

比较有意思的是该类中有两个重载的init()方法:

②init(ServletConfig)该带参的init()方法是 GenericServlet 抽象类实现 servlet接口要实现的init方法,该方法会在servlet被加载时被servlet容器调用并传入ServletConfig
③ init()该空参的init() 方法是GenericServlet 抽象了自己新添加的init方法,目的是让继承该抽象类的servlet被加载并初始化时可以自己做些自定义的初始化。GenericServlet 中带参的init方法是这样写的:

@Override

public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}

看到这里感觉继承 GenericServlet 抽象类再写servlet,必直接实现Servelt接口容易多了吧,别急后边还有更易用的就是HttpServlet

4.HttpServlet

该抽象类继承了GenericServlet 抽象类,并且重写了GenericServlet 中唯一的抽象方法service(ServletRequest,ServletRespone)方法我们来看看HttpServlet的方法

在这里插入图片描述

新的改变

该抽象类诸多方法读者可参看源码,我们就说一说其中的连个重载方法,service(ServletRequest , ServletResponse)该方法是HttpServlet继承GenericServlet实现的抽象方法,一个是HttpServlet自己定义的 service(HttpServletRequest, HttpServletResponse)方法

#####① service(ServletRequest , ServletResponse) 该方法作用是,由于我们的请求都是http请求,所以把ServletRequest请求下转型为HttpServletRequest(ServletRequest子接口),ServletRespone请求下转型为HttpServletRespone(ServletRespone子接口),以获取更多关于请求的信息(如请求方式等),并调用自定义的service方法,源代码:

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

HttpServletRequest  request;    HttpServletResponse response;    try {        request = (HttpServletRequest) req;        response = (HttpServletResponse) res;    } catch (ClassCastException e) {        throw new ServletException("non-HTTP request or response");    }    service(request, response);}
②service(HttpServletRequest, HttpServletResponse)自定义方法,根据请求的方式去调用不同的方法,源码如下:

protected void service(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

String method = req.getMethod();    if (method.equals(METHOD_GET)) {        long lastModified = getLastModified(req);        if (lastModified == -1) {            // servlet doesn't support if-modified-since, no reason            // to go through further expensive logic            doGet(req, resp);        } else {            long ifModifiedSince;            try {                ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);            } catch (IllegalArgumentException iae) {                // Invalid date header - proceed as if none was set                ifModifiedSince = -1;            }            if (ifModifiedSince < (lastModified / 1000 * 1000)) {                // If the servlet mod time is later, call doGet()                // Round down to the nearest second for a proper compare                // A ifModifiedSince of -1 will always be less                maybeSetLastModified(resp, lastModified);                doGet(req, resp);            } else {                resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);            }        }    } else if (method.equals(METHOD_HEAD)) {        long lastModified = getLastModified(req);        maybeSetLastModified(resp, lastModified);        doHead(req, resp);    } else if (method.equals(METHOD_POST)) {        doPost(req, resp);    } else if (method.equals(METHOD_PUT)) {        doPut(req, resp);    } else if (method.equals(METHOD_DELETE)) {        doDelete(req, resp);    } else if (method.equals(METHOD_OPTIONS)) {        doOptions(req,resp);    } else if (method.equals(METHOD_TRACE)) {        doTrace(req,resp);    } else {        //        // Note that this means NO servlet supports whatever        // method was requested, anywhere on this server.        //        String errMsg = lStrings.getString("http.method_not_implemented");        Object[] errArgs = new Object[1];        errArgs[0] = method;        errMsg = MessageFormat.format(errMsg, errArgs);        resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);    }}

看到这里你会觉得这下更简单了吧,当我们再新建servlet的时候只需要继承HttpServlet让后根据请求方式重写对应的doXXX()方法就行了吧!确实是。

前边讲了这么一堆,就讲了如何从Servlet迭代到HttpServlet这个过程,以及每个类或接口里边的方法。还没有说重点,为什么HttpServlet没有抽象方法,却定义成抽象类。

个人理解了好久觉得是这样的:如果HttpServlet不是抽象类的话,你就可以产生Httpser对象,但是单纯的HttpServlet对象时不能处理任何业务逻辑的,里边方法没有功能;
所以要定义成抽象类,防止你创建对象。
但是继承了HttpServlet类创建servlet就方便多了,你要根据自己需要然后重写需要的方法,让后自定义逻辑,这样就方便多了。
总结:HttpServlet抽象类没有抽象方式是为了避免你自己创建一个没有业务功能的HttpServlet对象,但是给你一个提供了这样一个类方面你的servlet开发。(原创个人拙见,欢迎讨论)

转载于:https://www.cnblogs.com/bianxianhua/p/9976218.html

你可能感兴趣的文章
写个软件来防止服务器网站CPU百分百
查看>>
智能城市里,“公共电话亭”的存在意味着什么?
查看>>
JVM分代垃圾回收策略的基础概念
查看>>
《交互式程序设计 第2版》一3.5 捕获简单用户交互行为
查看>>
安装操作系统需要注意的事项
查看>>
5G技术的5大猜想
查看>>
MongoDB 3.0(1):CentOS7 安装MongoDB 3.0服务
查看>>
别随便安装 Pokemon GO被曝藏恶意后门
查看>>
BBC即将推出Britflix流媒体服务:欲成为英国版Netflix
查看>>
让数据会思考会说话,为出海企业提供多样化数据智能解决方案
查看>>
我眼中的自动化测试框架设计要点
查看>>
FLIF:自由的无损图像格式
查看>>
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.7 总结
查看>>
Google开源Inception-ResNet-v2,提升图像分类水准
查看>>
Opera 出售细节曝光:昆仑出资1.68亿美元
查看>>
CentOS 5.3 下快速安装配置 PPTP ××× 服务器
查看>>
产品经理学习总结之技术和设计篇
查看>>
vue之组件认知
查看>>
23种设计模式(15):备忘录模式
查看>>
java基础学习总结——IO流
查看>>