美文网首页
深入剖析Tomcat(How Tomcat works)读书笔记

深入剖析Tomcat(How Tomcat works)读书笔记

作者: 抬头挺胸才算活着 | 来源:发表于2019-12-07 19:28 被阅读0次

参考资料:
[1]. 深入剖析Tomcat(How Tomcat works)书籍代码下载地址

  • 第五章:servlet容器
    servlet容器主要分为Engine,Host,Context,Wrapper四种。
    上一章讲到连接器会调用servlet容器的invoke方法,实际上调用到容器的管道的invoke方法,管道会依次调用它的各个阀门的invoke方法,最后调用容器的基础阀门。
    Wrapper的基础阀门负责载入相关联的servlet类,对请求进行响应。
public class SimpleWrapperValve implements Valve, Contained {

    protected Container container;

    public void invoke(Request request, Response response,
            ValveContext valveContext) throws IOException, ServletException {

        SimpleWrapper wrapper = (SimpleWrapper) getContainer();
        ServletRequest sreq = request.getRequest();
        ServletResponse sres = response.getResponse();
        Servlet servlet = null;
        HttpServletRequest hreq = null;
        if (sreq instanceof HttpServletRequest)
            hreq = (HttpServletRequest) sreq;
        HttpServletResponse hres = null;
        if (sres instanceof HttpServletResponse)
            hres = (HttpServletResponse) sres;

        // Allocate a servlet instance to process this request
        try {
            servlet = wrapper.allocate();
            if (hres != null && hreq != null) {
                servlet.service(hreq, hres);
            } else {
                servlet.service(sreq, sres);
            }
        } catch (ServletException e) {
        }
    }
}

Context的基础阀门SimpleContextValve负责找到对应的Wrapper容器,然后调用Wrapper容器的invoke方法。

public class SimpleContextValve implements Valve, Contained {

    protected Container container;

    public void invoke(Request request, Response response,
            ValveContext valveContext) throws IOException, ServletException {
        // Validate the request and response object types
        if (!(request.getRequest() instanceof HttpServletRequest)
                || !(response.getResponse() instanceof HttpServletResponse)) {
            return; // NOTE - Not much else we can do generically
        }

        // Disallow any direct access to resources under WEB-INF or META-INF
        HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
        String contextPath = hreq.getContextPath();
        String requestURI = ((HttpRequest) request).getDecodedRequestURI();
        String relativeURI = requestURI.substring(contextPath.length())
                .toUpperCase();

        Context context = (Context) getContainer();
        // Select the Wrapper to be used for this Request
        Wrapper wrapper = null;
        try {
            wrapper = (Wrapper) context.map(request, true);
        } catch (IllegalArgumentException e) {
            badRequest(requestURI, (HttpServletResponse) response.getResponse());
            return;
        }
        if (wrapper == null) {
            notFound(requestURI, (HttpServletResponse) response.getResponse());
            return;
        }
        // Ask this Wrapper to process this Request
        response.setContext(context);
        wrapper.invoke(request, response);
    }
}

Context中mappers存放着协议和Mapper的映射,Mapper.map负责从servletMappings中找出相对路径对应的Wrapper,servletMappings存放着相对URI和对应的Wrapper的名字,children中存放着Wrapper名字和对应的Wrapper实例。

    public Container map(Request request, boolean update) {
        // Identify the context-relative URI to be mapped
        String contextPath = ((HttpServletRequest) request.getRequest())
                .getContextPath();
        String requestURI = ((HttpRequest) request).getDecodedRequestURI();
        String relativeURI = requestURI.substring(contextPath.length());
        // Apply the standard request URI mapping rules from the specification
        Wrapper wrapper = null;
        String servletPath = relativeURI;
        String pathInfo = null;
        String name = context.findServletMapping(relativeURI);
        if (name != null)
            wrapper = (Wrapper) context.findChild(name);
        return (wrapper);
    }

相关文章

网友评论

      本文标题:深入剖析Tomcat(How Tomcat works)读书笔记

      本文链接:https://www.haomeiwen.com/subject/ywqygctx.html