HttpServlet及Servlet Container原理总结

Servlet顾名思义,服务器端应用程序,HttpServlet是用来处理基于Http的请求的服务器端程序,现在大部分请求都是基于Http的;
HttpServlet是一个继承自Servlet的抽象类HttpServlet API,继承自该类的subclass子类必须实现如下至少一个抽象方法

A subclass of HttpServlet must override at least one method, usually one of these:

doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself

那HttpServlet与Servlet Container的关系如何?后者是应用服务器,用来盛放HttpServlet应用程序的,如Tomcat,那处理一个请求并返回数据的过程是怎样的呢?

1、Web客户端向Servlet容器发送请求
2、容器解析http请求并封装成HttpServletRequest对象,同时创建一个HttpServletReponse对象
3、Servlet 容器调用HttpServlet的service()方法来接受HttpServletRequest和HttpServletReponse对象,
4、HttpServlet读取HttpServletRequest对象中的请求方法,从而确定调用doGet()\doPost….方法
5、经HttpServlet的相关处理产生相应数据,调用HttpServletReponse对象的方法从而把数据封装到HttpServletReponse对象中
6、Servlet容器把HttpServlet的响应结果返回给客户

总的来说,就是Servlet Container 存放Servlet应用程序,并把request封装成HttpServletRequest和HttpServletReponse一起传递给HttpServlet做详细处理,并把返回的HttpServletReponse返回给客户端

这里有一个疑问就是HttpServlet是一个抽象类,具体项目的Servlet继承该抽象类,并重写一系列方法,那什么时候override service()方法呢?
这里有两个service()方法,

 void   service(ServletRequest req, ServletResponse res)———— 
          Dispatches client requests to the protected service method.


protected  void service(HttpServletRequest req, HttpServletResponse resp)--- 
          Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class.

第一个方法接受的是ServletRequest 和ServletResponse参数,这个方法里可以判断request和reponse是否为HttpServletRequest和
HttpServletResponse类型的,不是的话则抛错,是的话则调用第二个service()方法并把参数也传给它;第二个service()主要就是接受请求并转发给具体的处理方法:doGet() or doPost or other ???

如下这个栗子(stackoverflow

@Override
public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException
{
    HttpServletRequest  request;
    HttpServletResponse response;

    if (!(req instanceof HttpServletRequest &&
            res instanceof HttpServletResponse)) {
        throw new ServletException("non-HTTP request or response");
    }

    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;

    service(request, response);
}
[...]
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 = req.getDateHeader(HEADER_IFMODSINCE);
            if (ifModifiedSince < lastModified) {
                // 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);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值