文档章节

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

寻找丢失的草帽儿
 寻找丢失的草帽儿
发布于 2016/04/11 20:34
字数 997
阅读 95
收藏 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
程序员
私信 提问
Servlet 中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
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
servlet(二)

servlet(二) 2015-12-25 by Damon servlet(一)中提到实现servlet接口,你可以写一个继承自javax.servlet.GenericServletr的genericServlet或继承自javax.servlet的HttpServlet,那GenericSe......

水天云黑白
2016/01/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring源码学习笔记-1-Resource

打算补下基础,学习下Spring源码,参考书籍是《Spring源码深度解析》,使用版本是Spring 3.2.x,本来想试图用脑图记录的,发现代码部分不好贴,还是作罢,这里只大略记录下想法,不写太细了 ...

zypy333
今天
10
0
RestClientUtil和ConfigRestClientUtil区别说明

RestClientUtil directly executes the DSL defined in the code. ConfigRestClientUtil gets the DSL defined in the configuration file by the DSL name and executes it. RestClientUtil......

bboss
今天
16
0

中国龙-扬科
昨天
2
0
Linux系统设置全局的默认网络代理

更改全局配置文件/etc/profile all_proxy="all_proxy=socks://rahowviahva.ml:80/"ftp_proxy="ftp_proxy=http://rahowviahva.ml:80/"http_proxy="http_proxy=http://rahowviahva.ml:80/"......

临江仙卜算子
昨天
10
0
java框架学习日志-6(bean作用域和自动装配)

本章补充bean的作用域和自动装配 bean作用域 之前提到可以用scope来设置单例模式 <bean id="type" class="cn.dota2.tpye.Type" scope="singleton"></bean> 除此之外还有几种用法 singleton:......

白话
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部