DispatcherServlet的继承体系和初始化

本文解析了Spring MVC中的核心组件DispatcherServlet的工作流程。从Servlet的继承体系出发,详细介绍了GenericServlet和HttpServlet的作用,并深入分析了DispatcherServlet如何处理HTTP请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DispatcherServlet的继承体系如图,

 

这两个顶层的抽象类属于java提供的servlet层级。

图中的5个servlet,有java提供的servlet,也有springmvc提供的servlet。

java提供的servlet:

  • GenericServlet抽象类,实现了Servlet接口
  • HttpServlet抽象类,继承了GenericServlet

spring提供的servlet

  • HttpServletBean
  • FrameworkServlet
  • DispatcherServlet

 

GenericServlet

GenericServlet主要做了2件事:

1.GenericServlet实现了Servlet接口的init(ServletConfig config)方法,获取了servlet的配置信息,如名称,servlet上下文ServletContext,参数等。

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

2.GenericServlet实现了Servlet接口的service(ServletRequest req, ServletResponse res),将其写为抽象方法,供下层实现。

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

 

HttpServlet

HttpServlet继承了GenericServlet,实现了GenericServlet的service(ServletRequest req, ServletResponse res)抽象方法,

在方法类,将ServletRequest,ServletResponse强转为HttpServletRequest,HttpServletResponse,

    @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);
    }

然后调用了HttpServlet自身的service(HttpServletRequest req, HttpServletResponse resp)方法。

   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);
        }
    }

在该方法中,根据请求方法的类型,调用对应的doXXX()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值