博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HttpServlet中的service()、doPost()、doGet()方法解析
阅读量:4092 次
发布时间:2019-05-25

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



1、service()方法源码解析

先来看HttpServlet的service()方法:

 

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对象,并强制转化为HttpServletRequest和HttpServletResponse类型的对象,在处理请求期间发生错误,会主动抛出异常。最后调用HttpServlet自身的service()方法,也就是第一种service()方法

 

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

  根据不同的请求会调用不同方法,当我们使用这些方法时根据不同的需求重写方法实现业务逻辑。如果请求不是以上的所有请求方式,该方法就会响应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错误的请求错误。

 

转载地址:http://driii.baihongyu.com/

你可能感兴趣的文章
使用Theia——构建你自己的IDE
查看>>
消失的这几个月我都干了什么
查看>>
.NET Core 3 WPF MVVM框架 Prism系列之命令
查看>>
索引-建立框架篇
查看>>
FPGA之IO信号类型深入理解
查看>>
JVM探秘:垃圾收集器
查看>>
机器学习(01)——机器学习简介
查看>>
[系列] Go 如何解析 JSON 数据?
查看>>
Nginx 究竟如何处理事件?
查看>>
菜鸟系列Fabric源码学习 — MVCC验证
查看>>
[白话解析] 深入浅出一致性Hash原理
查看>>
JVM探秘:垃圾收集器
查看>>
C#反射与特性(二):探究反射
查看>>
【趣味设计模式系列】之【状态模式】
查看>>
编译GLib C程序
查看>>
从两个角度理解为什么 JS 中没有函数重载
查看>>
图解Go语言的context了解编程语言核心实现源码
查看>>
ReentrantLock 源码分析从入门到入土
查看>>
看了多篇2019年的面经后的个人总结
查看>>
很多程序员多年都没掌握的异常处理技巧和原则
查看>>