tomcat源码分析学习笔记(五)

本文深入探讨了Servlet容器中简单上下文的概念,包括其内部结构、如何通过映射查找对应的处理器,以及如何配置上下文以实现不同协议下的请求处理。通过实例分析,展示了上下文在Servlet生命周期中的关键作用。

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

——每天的寥寥几笔,坚持下去,将会是一份份沉甸甸的积累


上一篇文章讲到了servlet容器的wrapper,这篇继续上一篇来讲讲第二种容器context。

之前讲过context的层次在wrapper之上,可以包含多个wrapper,一个wrapper完成对一个serlvet的处理,多个wrapper的时候,我们就要面临选择,确定到底由哪个wrapper来处理,也就是涉及到了映射查找对应的wrapper。


1.先来看看一个simpleContext

<span style="font-size:12px;">public class SimpleContext implements Context, Pipeline {

  public SimpleContext() {
    pipeline.setBasic(new SimpleContextValve());//依旧是设置基础阀,同上一篇文章的介绍
  }

  protected HashMap children = new HashMap();//添加子wrapper
  protected Loader loader = null;
  protected SimplePipeline pipeline = new SimplePipeline(this);//同上一篇文章
  protected HashMap servletMappings = new HashMap();//URL下的servlet与相应wrapper的键值对映射******
  //映射器。为了支持不同的协议。注意是协议。比如http,https两个协议,如果请求相同的servlet,处理的wrapper是不一样的
  protected Mapper amapper = null;//默认映射器
  protected HashMap mappers = new HashMap();//所有可用的映射器,第一个添加到容器中的映射器为默认映射器
  private Container parent = null;</span>


2.那又是如何映射查找对应的wrapper。流程如下:

(1)起点定在基础阀(因为基础阀负责创建出serlvet实例,调用service方法)。

<span style="font-size:12px;"> wrapper = (Wrapper) context.map(request, true);</span>


(2)调用Context的map方法,判断传入的request对象的协议是否符合要求,不符合返回null,符合则调用SimpleContextMapper的map方法

<span style="font-size:12px;">  public Container map(Request request, boolean update) {
    Mapper mapper = findMapper(request.getRequest().getProtocol());
    if (mapper == null)
      return (null);
    return (mapper.map(request, update));
  }</span>


(3)调用SimpleContextMapper的map方法。通过协议的测试后,就直接开始解析requestURL中请求的serlvet名,根据serlvet名映射找到具体wrapper名

<span style="font-size:12px;">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);//根据serlvet名映射查找serlvetMappings那张hashmap,找到具体wrapper名
    if (name != null)
      wrapper = (Wrapper) context.findChild(name);//根据上面找到的wrapper名,确定Context的child Wrappper.
    return (wrapper);
  }</span>


(4)拿到了wrapper,后面的操作同前一篇的操作,可参考tomcat源码分析学习笔记(三)


(5)最后贴上测试的启动类,那就更明晰了。

public final class Bootstrap2 {
  public static void main(String[] args) {
    HttpConnector connector = new HttpConnector();
    Wrapper wrapper1 = new SimpleWrapper();
    wrapper1.setName("Primitive");//给wrapper取名
    wrapper1.setServletClass("PrimitiveServlet");
    
    Wrapper wrapper2 = new SimpleWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new SimpleContext();
    context.addChild(wrapper1);
    context.addChild(wrapper2);

    Valve valve1 = new HeaderLoggerValve();
    Valve valve2 = new ClientIPLoggerValve();

    ((Pipeline) context).addValve(valve1);
    ((Pipeline) context).addValve(valve2);

    Mapper mapper = new SimpleContextMapper();
    mapper.setProtocol("http");
    context.addMapper(mapper);
    Loader loader = new SimpleLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");//添加requestUrl的解析结果和wrapper的映射关系
    context.addServletMapping("/Modern", "Modern");
    connector.setContainer(context);
    try {
      connector.initialize();
      connector.start();

      // make the application wait until we press a key.
      System.in.read();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}


就写到这吧,有什么问题欢迎提出。学生党天天熬夜,也是蛮拼的了。一起加油。



资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在本文中,我们将探讨如何通过 Vue.js 实现一个带有动画效果的“回到顶部”功能。Vue.js 是一款用于构建用户界面的流行 JavaScript 框架,其组件化和响应式设计让实现这种交互功能变得十分便捷。 首先,我们来分析 HTML 代码。在这个示例中,存在一个 ID 为 back-to-top 的 div 元素,其中包含两个 span 标签,分别显示“回到”和“顶部”文字。该 div 元素绑定了 Vue.js 的 @click 事件处理器 backToTop,用于处理点击事件,同时还绑定了 v-show 指令来控制按钮的显示与隐藏。v-cloak 指令的作用是在 Vue 实例渲染完成之前隐藏该元素,避免出现闪烁现象。 CSS 部分(backTop.css)主要负责样式设计。它首先清除了一些默认的边距和填充,对 html 和 body 进行了全屏布局,并设置了相对定位。.back-to-top 类则定义了“回到顶部”按钮的样式,包括其位置、圆角、阴影、填充以及悬停时背景颜色的变化。此外,与 v-cloak 相关的 CSS 确保在 Vue 实例加载过程中隐藏该元素。每个 .page 类代表一个页面,每个页面的高度设置为 400px,用于模拟多页面的滚动效果。 接下来是 JavaScript 部分(backTop.js)。在这里,我们创建了一个 Vue 实例。实例的 el 属性指定 Vue 将挂载到的 DOM 元素(#back-to-top)。data 对象中包含三个属性:backTopShow 用于控制按钮的显示状态;backTopAllow 用于防止用户快速连续点击;backSeconds 定义了回到顶部所需的时间;showPx 则规定了滚动多少像素后显示“回到顶部”按钮。 在 V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值