当前位置: 首页 > news >正文

现在做网站有前途吗/山东泰安网络推广

现在做网站有前途吗,山东泰安网络推广,适合服务行业做推广的网站,丛台企业做网站推广从零开始手写Tomcat的教程13节---Host和EngineHost接口StandardHost实现类StandardHostValve类StandardHostWrapper类为什么必须要有一个Host容器应用程序小结Engine接口StandardEngine类StandardEngineValve类应用程序小结Host接口 public interface Host extends Container {…

从零开始手写Tomcat的教程13节---Host和Engine

  • Host接口
    • StandardHost实现类
    • StandardHostValve类
    • StandardHostWrapper类
    • 为什么必须要有一个Host容器
    • 应用程序
    • 小结
  • Engine接口
    • StandardEngine类
    • StandardEngineValve类
    • 应用程序
  • 小结


在这里插入图片描述


Host接口

在这里插入图片描述

public interface Host extends Container {// ----------------------------------------------------- Manifest Constants/*** The ContainerEvent event type sent when a new alias is added* by <code>addAlias()</code>.*/public static final String ADD_ALIAS_EVENT = "addAlias";/*** The ContainerEvent event type sent when an old alias is removed* by <code>removeAlias()</code>.*/public static final String REMOVE_ALIAS_EVENT = "removeAlias";// ------------------------------------------------------------- Properties/*** Return the application root for this Host.  This can be an absolute* pathname, a relative pathname, or a URL.*/public String getAppBase();/*** Set the application root for this Host.  This can be an absolute* pathname, a relative pathname, or a URL.** @param appBase The new application root*/public void setAppBase(String appBase);/*** Return the value of the auto deploy flag.  If true, it indicates that * this host's child webapps should be discovred and automatically * deployed.*/public boolean getAutoDeploy();/*** Set the auto deploy flag value for this host.* * @param autoDeploy The new auto deploy flag*/public void setAutoDeploy(boolean autoDeploy);/*** Set the DefaultContext* for new web applications.** @param defaultContext The new DefaultContext*/public void addDefaultContext(DefaultContext defaultContext);/*** Retrieve the DefaultContext for new web applications.*/public DefaultContext getDefaultContext();/*** Return the canonical, fully qualified, name of the virtual host* this Container represents.*/public String getName();/*** Set the canonical, fully qualified, name of the virtual host* this Container represents.** @param name Virtual host name** @exception IllegalArgumentException if name is null*/public void setName(String name);// --------------------------------------------------------- Public Methods/*** Import the DefaultContext config into a web application context.** @param context web application context to import default context*/public void importDefaultContext(Context context);/*** Add an alias name that should be mapped to this same Host.** @param alias The alias to be added*/public void addAlias(String alias);/*** Return the set of alias names for this Host.  If none are defined,* a zero length array is returned.*/public String[] findAliases();/*** Return the Context that would be used to process the specified* host-relative request URI, if any; otherwise return <code>null</code>.** @param uri Request URI to be mapped*/public Context map(String uri);/*** Remove the specified alias name from the aliases for this Host.** @param alias Alias name to be removed*/public void removeAlias(String alias);}

在这里插入图片描述


StandardHost实现类

在这里插入图片描述

    /*** Create a new StandardHost component with the default basic Valve.*/public StandardHost() {super();pipeline.setBasic(new StandardHostValve());}
      <Host name="www.dhy.com"  appBase="dhy"unpackWARs="true" autoDeploy="true"><context path="/xpy" docBase="xpy" ></context></Host>

Deployer接口具体是干啥的,大家看了上面的xml配置,估计就会明白了。

Host对应一个域名,该域名在操作系统层面的文件系统中映射到一个目录,该目录下可以有很多子目录,这些子目录会挨个映射到当前Host下面所管理的context容器上去

在这里插入图片描述

   /*** Start this host*/public synchronized void start() throws LifecycleException {// Set error report valveif ((errorReportValveClass != null)&& (!errorReportValveClass.equals(""))) {try {Valve valve = (Valve) Class.forName(errorReportValveClass).newInstance();addValve(valve);} catch (Throwable t) {log(sm.getString("standardHost.invalidErrorReportValveClass", errorReportValveClass));}}// Set dispatcher valveaddValve(new ErrorDispatcherValve());super.start();}

在这里插入图片描述

    /*** The Java class name of the default error reporter implementation class * for deployed web applications.*/private String errorReportValveClass ="org.apache.catalina.valves.ErrorReportValve";

这里Host的start初始化方法主要就是添加了两个关于错误日志处理的阀门,随后调用父类ContainerBase的start方法,启动相关组件,调用子容器的start初始化方法,因为这些逻辑都是通用的,因此都放到了父类的start方法中实现

父类ContainerBase的start方法/*** Prepare for active use of the public methods of this Component.** @exception LifecycleException if this component detects a fatal error*  that prevents it from being started*/@Overridepublic synchronized void start() throws LifecycleException {// Validate and update our current component stateif (started)throw new LifecycleException(sm.getString("containerBase.alreadyStarted", logName()));// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);addDefaultMapper(this.mapperClass);started = true;// Start our subordinate components, if anyif ((loader != null) && (loader instanceof Lifecycle))((Lifecycle) loader).start();if ((logger != null) && (logger instanceof Lifecycle))((Lifecycle) logger).start();if ((manager != null) && (manager instanceof Lifecycle))((Lifecycle) manager).start();if ((cluster != null) && (cluster instanceof Lifecycle))((Lifecycle) cluster).start();if ((realm != null) && (realm instanceof Lifecycle))((Lifecycle) realm).start();if ((resources != null) && (resources instanceof Lifecycle))((Lifecycle) resources).start();// Start our Mappers, if anyMapper mappers[] = findMappers();for (int i = 0; i < mappers.length; i++) {if (mappers[i] instanceof Lifecycle)((Lifecycle) mappers[i]).start();}// Start our child containers, if anyContainer children[] = findChildren();for (int i = 0; i < children.length; i++) {if (children[i] instanceof Lifecycle)((Lifecycle) children[i]).start();}// Start the Valves in our pipeline (including the basic), if anyif (pipeline instanceof Lifecycle)((Lifecycle) pipeline).start();// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(START_EVENT, null);// Notify our interested LifecycleListenerslifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);}

在这里插入图片描述
ContainerBase类的invoke方法因为是通用逻辑抽取,因此实现是固定的:

    public void invoke(Request request, Response response)throws IOException, ServletException {//调用当前容器管道中的阀门进行处理pipeline.invoke(request, response);}

StandardHostValve类

在这里插入图片描述

StandardHostValve的invoke方法如下:

   public void invoke(Request request, Response response,ValveContext valveContext)throws IOException, ServletException {// Validate the request and response object typesif (!(request.getRequest() instanceof HttpServletRequest) ||!(response.getResponse() instanceof HttpServletResponse)) {return;     // NOTE - Not much else we can do generically}// Select the Context to be used for this RequestStandardHost host = (StandardHost) getContainer();//根据map方法找到当前请求对应的context对象Context context = (Context) host.map(request, true);if (context == null) {((HttpServletResponse) response.getResponse()).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,sm.getString("standardHost.noContext"));return;}// Bind the context CL to the current threadThread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());//如果存在session的话,更新最后一次访问的时间// Update the session last access time for our session (if any)HttpServletRequest hreq = (HttpServletRequest) request.getRequest();String sessionId = hreq.getRequestedSessionId();if (sessionId != null) {Manager manager = context.getManager();if (manager != null) {Session session = manager.findSession(sessionId);if ((session != null) && session.isValid())session.access();}}// Ask this Context to process this request//将当前请求接着传递给找到的context对象进行处理context.invoke(request, response);}

在这里插入图片描述


在这里插入图片描述

这里调用的其实是父类ContainerBase的map方法:

    public Container map(Request request, boolean update) {// Select the Mapper we will useMapper mapper = findMapper(request.getRequest().getProtocol());if (mapper == null)return (null);// Use this Mapper to perform this mapping//这里最终调用的是StandardHostMapper的map方法,下面再分析,这里最终传入的其实就是请求URI中的context路径部分return (mapper.map(request, update));}

StandardHost类的map方法:

    public Context map(String uri) {if (debug > 0)log("Mapping request URI '" + uri + "'");if (uri == null)return (null);// Match on the longest possible context path prefixif (debug > 1)log("  Trying the longest context path prefix");Context context = null;//拿到当前请求context路径部分String mapuri = uri;while (true) {//去子容器中找到该contextcontext = (Context) findChild(mapuri);if (context != null)break;int slash = mapuri.lastIndexOf('/');if (slash < 0)break;mapuri = mapuri.substring(0, slash);}// If no Context matches, select the default Contextif (context == null) {if (debug > 1)log("  Trying the default context");context = (Context) findChild("");}// Complain if no Context has been selectedif (context == null) {log(sm.getString("standardHost.mappingError", uri));return (null);}// Return the mapped Context (if any)if (debug > 0)log(" Mapped to context '" + context.getPath() + "'");return (context);}

StandardHostWrapper类

在这里插入图片描述
在这里插入图片描述
说明继承了ContainerBase的容器,只要调用了父类的start方法,就会添加一个默认的映射器

    protected void addDefaultMapper(String mapperClass) {// Do we need a default Mapper?if (mapperClass == null)return;if (mappers.size() >= 1)return;// Instantiate and add a default Mappertry {Class clazz = Class.forName(mapperClass);Mapper mapper = (Mapper) clazz.newInstance();mapper.setProtocol("http");addMapper(mapper);} catch (Exception e) {log(sm.getString("containerBase.addDefaultMapper", mapperClass),e);}}

在这里插入图片描述

    /*** The Java class name of the default Mapper class for this Container.*/private String mapperClass ="org.apache.catalina.core.StandardHostMapper";

在这里插入图片描述
上面源码已经给出过了
在这里插入图片描述
关于这一点可以参考第12节

在这里插入图片描述

    public Container map(Request request, boolean update) {// Has this request already been mapped?if (update && (request.getContext() != null))return (request.getContext());// Perform mapping on our request URIString uri = ((HttpRequest) request).getDecodedRequestURI();//调用Host的map方法获得当前URI对应的context对象Context context = host.map(uri);// Update the request (if requested) and return the selected Contextif (update) {request.setContext(context);if (context != null)((HttpRequest) request).setContextPath(context.getPath());else((HttpRequest) request).setContextPath(null);}return (context);}

为什么必须要有一个Host容器

在这里插入图片描述

在这里插入图片描述
applicationConfig方法主要是来解析web.xml配置文件的,该方法在start方法中被调用,start方法在ContextConfig监听到Context容器的启动的start事件时,被调用。


应用程序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
connector改为关联一个Host了,然后会设置Host下面的context,host对应的域名和目录名


小结

Host洋洋洒洒讲了那么多,下面对Host这部分内容做一个小结先:

在这里插入图片描述


Engine接口

在这里插入图片描述

public interface Engine extends Container {// ------------------------------------------------------------- Properties/*** Return the default hostname for this Engine.*/public String getDefaultHost();/*** Set the default hostname for this Engine.** @param defaultHost The new default host*/public void setDefaultHost(String defaultHost);/*** Retrieve the JvmRouteId for this engine.*/public String getJvmRoute();/*** Set the JvmRouteId for this engine.** @param jvmRouteId the (new) JVM Route ID. Each Engine within a cluster*        must have a unique JVM Route ID.*/public void setJvmRoute(String jvmRouteId);/*** Return the <code>Service</code> with which we are associated (if any).*/public Service getService();/*** Set the <code>Service</code> with which we are associated (if any).** @param service The service that owns this Engine*/public void setService(Service service);/*** Set the DefaultContext* for new web applications.** @param defaultContext The new DefaultContext*/public void addDefaultContext(DefaultContext defaultContext);/*** Retrieve the DefaultContext for new web applications.*/public DefaultContext getDefaultContext();// --------------------------------------------------------- Public Methods/*** Import the DefaultContext config into a web application context.** @param context web application context to import default context*/public void importDefaultContext(Context context);}

在这里插入图片描述


StandardEngine类

在这里插入图片描述

    /*** Create a new StandardEngine component with the default basic Valve.*/public StandardEngine() {super();pipeline.setBasic(new StandardEngineValve());}

在这里插入图片描述

    /*** Add a child Container, only if the proposed child is an implementation* of Host.** @param child Child container to be added*/public void addChild(Container child) {if (!(child instanceof Host))throw new IllegalArgumentException(sm.getString("standardEngine.notHost"));super.addChild(child);}

在这里插入图片描述

    /*** Disallow any attempt to set a parent for this Container, since an* Engine is supposed to be at the top of the Container hierarchy.** @param container Proposed parent Container*/public void setParent(Container container) {throw new IllegalArgumentException(sm.getString("standardEngine.notParent"));}

StandardEngineValve类

在这里插入图片描述

    public void invoke(Request request, Response response,ValveContext valveContext)throws IOException, ServletException {// Validate the request and response object typesif (!(request.getRequest() instanceof HttpServletRequest) ||!(response.getResponse() instanceof HttpServletResponse)) {return;     // NOTE - Not much else we can do generically}// Validate that any HTTP/1.1 request included a host headerHttpServletRequest hrequest = (HttpServletRequest) request;if ("HTTP/1.1".equals(hrequest.getProtocol()) &&(hrequest.getServerName() == null)) {((HttpServletResponse) response.getResponse()).sendError(HttpServletResponse.SC_BAD_REQUEST,sm.getString("standardEngine.noHostHeader",request.getRequest().getServerName()));return;}// Select the Host to be used for this RequestStandardEngine engine = (StandardEngine) getContainer();//通过request找到对应的host,不用我多说了吧,和context的步骤基本一致Host host = (Host) engine.map(request, true);if (host == null) {((HttpServletResponse) response.getResponse()).sendError(HttpServletResponse.SC_BAD_REQUEST,sm.getString("standardEngine.noHost",request.getRequest().getServerName()));return;}// Ask this Host to process this requesthost.invoke(request, response);}

在这里插入图片描述
在这里插入图片描述


应用程序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


小结

在这里插入图片描述

http://www.lbrq.cn/news/1357525.html

相关文章:

  • 如何自己做免费网站/seo工具
  • 垂直行业门户网站/品牌维护
  • 网盘搜索网站 怎么做/外贸推广平台怎么做
  • 黑龙江省机场建设集团官网网站/进入百度首页官网
  • 自力教育/大连seo建站
  • wordpress图片放大/武汉网站优化公司
  • 做网站的dreamweaver/百度指数分析案例
  • 做网站需要哪些东西/东莞网站建设推广品众
  • 下载手机软件的app/武汉seo技术
  • 展示型网站建设价格/怎么推广一个网站
  • 网站怎么做cp备案号/一个完整的产品运营方案
  • 做传感器交易的网站/如何在网站上推广自己的产品
  • 建筑工地网站有哪些/购买链接怎么买
  • 不同的网站 做301/网页设计排版布局技巧
  • 建设商务公司网站/大作设计网站
  • 揭阳 网站建设/视频号怎么推广流量
  • 怎么建网站手机版/北京seo顾问外包
  • 廊坊市做网站/什么是营销渠道
  • 做网站数据库怎么整/西安网站建设维护
  • 网站开发个人简介范文/域名解析ip
  • 网站开发服务承诺书/推广员是做什么的
  • 武汉新闻网/网站首页的优化
  • asp网站开发人员招聘/如何申请一个网站域名
  • 大访问量的网站怎么做优化/网站接广告平台
  • 网站建设基本流程心得/网络营销的基本流程
  • 深圳品牌网站设计推广/网站设计与网页制作
  • 平台网站怎么做的好/b站怎么推广
  • phpnow wordpress/网络推广优化
  • 史上最强大的搜索神器/seo整站优化多少钱
  • 做相册网站/网络营销的手段有哪些
  • sqli-labs靶场less40-less45
  • docker容器临时文件去除,服务器容量空间
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-邮箱重置密码
  • 力扣热题100------21.合并两个有序链表
  • 数据集相关类代码回顾理解 | np.mean\transforms.Normalize\transforms.Compose\xxx.transform
  • Bean的生命周期和循环依赖问题的解决