文档章节

HttpServlet中的service()、doPost()、doGet()方法解析

寻找丢失的草帽儿
 寻找丢失的草帽儿
发布于 2016/04/11 20:34
字数 997
阅读 74
收藏 0

1、service()方法源码解析

先来看HttpServletservice()方法:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 
        //获取http request的method参数,其实就是html的form标签  
//中method属性对应的字符串 
        String method = req.getMethod();
        long errMsg;
//判断请求方式
        if(method.equals("GET")) {
//获取最后被修改时间 
            errMsg = this.getLastModified(req);
            if(errMsg == -1L) {
/**如果servlet不支持http request header的if-modified-since属性 
* 则继续处理 
**/  
                this.doGet(req, resp);
            } else {
//如果支持这个属性 
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }
/** 
* 如果客户端的文件最后修改时间和服务器端的文件最后修改时间一致则返回304不需要修改状态 
* 这样服务器就不返回html,浏览器读取本地缓存文件,否则重新获取服务器端的对应html文件 
             **/  
                if(ifModifiedSince < errMsg / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, errMsg);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if(method.equals("HEAD")) {
            errMsg = this.getLastModified(req);
            this.maybeSetLastModified(resp, errMsg);
            this.doHead(req, resp);
        } else if(method.equals("POST")) {
            this.doPost(req, resp);
        } else if(method.equals("PUT")) {
            this.doPut(req, resp);
        } else if(method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if(method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if(method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            //如果请求不是以上的所有请求方式,该方法就会响应501错误,也就是不支持这种请求
            String errMsg1 = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg1 = MessageFormat.format(errMsg1, errArgs);
            resp.sendError(501, errMsg1);
        }
 
    }
 
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException("non-HTTP request or response");
        }
        this.service(request, response);
}

很显然HttpServlet这个类里面有两个service()方法。首先要知道的是用户自定义的Servlet都是HttpServlet的子类,也就是要继承HttpServlet,而HttpServlet是从GenericServlet继承而来,GenericServlet类要实现javax.servlet.Servlet接口。而GenericServlet类提供的除service()方法以外所有接口方法都默认实现。所以service()是一个抽象方法,GenericServlet的派生类必须对该方法重置才能实现期望的业务逻辑。

 

先说以上HttpServlet的第二种service()方法,该方法是来自父类GenericServlet

HttpServlet将其重置。该方法收到客服端请求后,创建request对象和response对象,并强制转化为HttpServletRequestHttpServletResponse类型的对象,在处理请求期间发生错误,会主动抛出异常。最后调用HttpServlet自身的service()方法,也就是第一种service()方法

 

然后我们来看第一种service()方法,客服端发送请求至服务器端,服务器将请求发送到Servlet,首先会调用init()方法初始化Servlet,然后Servlet的执行时期会调用service()方法,该方法会自动判断来自客服端的请求方式,根据不同请求方式调用不同方法,如果是get请求,则调用doGet()方法,如果是post请求,则调用doPost()方法。我们可以看到里面的请求方式有HEADGETPOSTDELETEOPTIONSTRACE

  根据不同的请求会调用不同方法,当我们使用这些方法时根据不同的需求重写方法实现业务逻辑。如果请求不是以上的所有请求方式,该方法就会响应501错误,也就是不支持这种请求。处理完请求后自然要返回响应,最后调用destory()方法销毁Servlet


2、doGet()和doPost()方法源码解析

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取协议 
        String protocol = req.getProtocol();
//获取http.method_get_not_supported的国际化字符串
        String msg = lStrings.getString("http.method_get_not_supported");
        if(protocol.endsWith("1.1")) {
//如果是HTTP/1.1,返回405禁止访问方法错误
            resp.sendError(405, msg);
        } else {
//如果不是HTTP/1.1,返回400错误的请求错误  
            resp.sendError(400, msg);
        }
 
    }
 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if(protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }
 
}

两个方法如果不被重写,那执行时默认会调用HttpServlet的代码,首先获取协议,然后获取国际化字符串,最后判断协议,如果协议为HTTP/1.1,返回405禁止访问方法错误,//如果不是HTTP/1.1,返回400错误的请求错误


© 著作权归作者所有

共有 人打赏支持
寻找丢失的草帽儿
粉丝 1
博文 5
码字总数 4136
作品 0
程序员
HTTPServlet 的service() doGet() doPost()方法关系

版权声明:本文为博主原创文章,欢迎大家讨论,未经博主允许不得转载. https://blog.csdn.net/u010398771/article/details/82758022 1、HttpServlet 使用一个 HTML 表格来发送和接收数据。要创...

长河
09/18
0
0
Servlet中doGet和doPost等方法

Serlvet接口只定义了一个服务方法就是service,而HttpServlet类实现了该方法并且要求调用下列的方法之一: doGet:处理GET请求 doPost:处理POST请求 当发出客户端请求的时候,调用service 方...

yifon
2014/04/19
0
0
Servlet doGet和doPost方法

首先你要明确servlet的生命周期和HTTP协议. Serlvet接口只定义了一个服务方法就是service,而HttpServlet类实现了该方法并且要求调用下列的方法之一: doGet:处理GET请求 doPost:处理POST请...

xiahuawuyu
2012/08/02
0
0
Java Servlet API(主要的方法)

Java Servlet 开发工具(JSDK)提供了多个软件包,在编写Servlet时需要用到这些软件包,下面主要介绍HTTP Servlet应用编程接口。 HttpServlet类包含init()、destroy()、Service()等方法...

晨曦之光
2012/05/16
333
0
Eclipse+Tomcat配置中遇到的错误

1 eclipse发布项目报错:Multiple Contexts hava a path of “/xxx“ 1.1在Eclipse的Servers中单击“server.xml”文件并打开 1.2在"server.xml"文件中,可以看到重复定义的context,删掉1个即...

510202
2015/03/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

安全管理标准

安全生产严重等级分类: 故障频次: 风险等级矩阵:

乔老哥
11分钟前
1
0
数据结构“树”的相关微视频

今天在腾讯视频上闲逛,然後发现一个叫“岚人”的用户上传了几段小视频,基本上都在5分钟以内,讲解了关于树的一些结构和算法。零代码,非常适合初学者入门。不过,对于老鸟来说,这也是非常...

Iridium
23分钟前
0
0
10-利用思维导图梳理JavaSE-Java 集合

10-利用思维导图梳理JavaSE-Java 集合 主要内容 1.Collection接口 2.Set接口 2.1.Set接口概述 2.2.HashSet类 2.3.TreeSet类 2.4.SortedSet接口 3.List接口 3.1.List接口概述 3.2.ArrayList类...

飞鱼说编程
34分钟前
3
0
活动推荐|互联网3.0与区块链新时代论坛(北京)

1 时间地点 **时间:**9月22日 14:00 - 18:00 地点:(北京海淀)西大街70号 3w咖啡 二层 2 活动详情 Harmony创始人Stephen及团队将介绍他们的区块链分片扩容技术。Stephen曾任Apple地图服务...

HiBlock
52分钟前
1
0
如何优雅的删除Redis的大key

关于Redis大键(Key),我们从[空间复杂性]和访问它的[时间复杂度]两个方面来定义大键。前者主要表示Redis键的占用内存大小;后者表示Redis集合数据类型(set/hash/list/sorted set)键,所含有的...

IT--小哥
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部