CoyoteAdapter-我是沟通的桥梁(四)

CoyoteAdapter-我是沟通的桥梁

​在前面说过,由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat 定义了自己的 Request 类来“存放”这些请求信息。ProtocolHandler 接口负责解析请求并生成 Tomcat Request 类。但是这个 Request 对象不是标准的 ServletRequest,也就意味着,不能用 Tomcat Request 作为参数来调用容器。Tomcat 设计者的解决方案是引入 CoyoteAdapter,这是适配器模式的经典运用,连接器调用 CoyoteAdapter 的 Sevice 方法,传入的是 Tomcat Request 对象,CoyoteAdapter 负责将 Tomcat Request 转成 ServletRequest,再调用容器的 Service 方法。

连接器流程图

从图中我们看到,EndPoint 接收到 Socket 连接后,生成一个 SocketProcessor 任务提交到线程池去处理,SocketProcessor 的 Run 方法会调用 Processor 组件去解析应用层协议,Processor 通过解析生成 Request 对象后,会调用 Adapter 的 Service 方法。

在这里插入图片描述

Adapter 组件

​ 通过前面Http11Processor解析后,最后调用用service

//获取CoyoteAdapter,调用其service方法
getAdapter().service(request, response);

​ 现在我们主要分析一下Adapter的service源码

public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
        throws Exception {
    //org.apache.catalina.connector.Request,实现了javax.servlet.http.HttpServletRequest接口
    Request request = (Request) req.getNote(ADAPTER_NOTES);
    //org.apache.catalina.connector.Response,实现了javax.servlet.http.HttpServletResponse接口
    Response response = (Response) res.getNote(ADAPTER_NOTES);

    if (request == null) {
        // Create objects
        // 创建对象
        request = connector.createRequest();
        request.setCoyoteRequest(req);
        response = connector.createResponse();
        response.setCoyoteResponse(res);

        // Link objects
        request.setResponse(response);
        response.setRequest(request);

        // Set as notes
        req.setNote(ADAPTER_NOTES, request);
        res.setNote(ADAPTER_NOTES, response);

        // Set query string encoding
        // 设置请求编码方式
        req.getParameters().setQueryStringCharset(connector.getURICharset());
    }
		。。。。

    try {
        // Parse and set Catalina and configuration specific
        // request parameters
        //解析并设置Catalina和配置特定的请求参数
        postParseSuccess = postParseRequest(req, request, res, response);
        if (postParseSuccess) {
            //check valves if we support async
            request.setAsyncSupported(
                    connector.getService().getContainer().getPipeline().isAsyncSupported());
            // Calling the container
            //调用容器
            // 使用Container去处理请求
            // getFirst的返回对象是Valve,在Tomcat初始化的时候存放在容器中
            connector.getService().getContainer().getPipeline().getFirst().invoke(
                    request, response);
          。。。。。
      

总结

​Tomcat 的整体架构包含了两个核心组件连接器和容器。连接器负责对外交流,容器负责内部处理。连接器用 ProtocolHandler 接口来封装通信协议和 I/O 模型的差异,ProtocolHandler 内部又分为 EndPoint 和 Processor 模块,EndPoint 负责底层 Socket 通信,Proccesor 负责应用层协议解析。连接器通过适配器 Adapter 调用容器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
31-May-2023 21:55:15.359 信息 [http-nio-8080-exec-6] org.apache.catalina.core.ApplicationContext.log 将servlet[com.LdfandWh.servlet.CheckCodeServlet]标记为不可用 31-May-2023 21:55:15.359 严重 [http-nio-8080-exec-6] org.apache.catalina.core.StandardWrapperValve.invoke 分配异常的servlet [com.LdfandWh.servlet.CheckCodeServlet] java.lang.ClassNotFoundException: com.LdfandWh.servlet.CheckCodeServlet at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188) at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:539) at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:520) at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1042) at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
06-01

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值