首页 > 代码库 > how tomcat works 5 servlet容器 下
how tomcat works 5 servlet容器 下
上一节,我们主要说的是Wrapper容器,这一节我们说Context容器。
再重申一遍,一个Context容器可以包含多个Wrapper容器;
一个Wrapper容器就表示一个独立的servlet。
首先咱们得明确几点;
映射器的作用就是联系一个父容器与他的若干个子容器,一个父容器可以有若干个映射器,为什么?因为有这样可以支持不同的协议。
例如一个映射器用来支持http协议,另一个映射器支持https协议(话说,http与https有什么区别,我就说一点,那个s代表security,安全,采取了另一种形式的保密措施,一般银行,证券交易所用https)
Mapper接口如下,我们这节使用的是其实现类,SimpleContextMapper类
各个方法的名字都起的很好,大家应该可以见名知意。
下面是这一节的uml类图
通过说明的uml图,大家可以看到我们熟悉的SimpleContext"含有"一个SimpleContextMapper,现在我们看看代码
现在我来说说这个几个属性;
mapper这是一个Mapper类型的是属性,如果一个容器只有一个映射器的话,那么就默认是它;如果一个容器有若干个映射器(以应对不同的网络协议例如http与https)那么mapper就置为空;
mappers这是hashmap类型的,里面放置容器的若干个映射器,以映射器支持的协议作为key;
servletMapping 也是hashmap,里面存放的是一个个映射路径与子容器的映射关系;例如如果访问uri为/servletA,就对应servletA这个servlet;
childen又是一个hashmap,里面存放了servletA这个名字对于的子容器(在这里就是Wrapper)
测试类如下;
我直接从Context容器里的基础阀讲起,就是它SimpleContextValve(上一节的基础阀是SimpleWrapperValve)。基础阀之前的流程与上一节的内容一样,大家参照上一节。
ok我们到SimpleContext的map方法里看看;
findMapper方法总是返回默认的那个映射器(前面我们已经说了,如果容器中只有一个映射器那它就是默认的,如果有多个,那么存储默认映射器的属性为空)如果有多个映射器就到mappers里去按照网络协议找;
找到映射器之后,就简单了
wrapper.invoke(request, response);
这就回到上一节那部分了,调用Wrapper的所有阀,直到基础阀(在这一节里,wrapper的管道里只有基础阀,之前的两个阀,装到了context的管道里),进入wrapper后调用allocate.......
再重申一遍,一个Context容器可以包含多个Wrapper容器;
一个Wrapper容器就表示一个独立的servlet。
Context应用程序
这里我们得提出一个新的组件----映射器,它帮助servlet容器---在这一节汇总就是Context实例选择一个子容器(这里就是Wrapper实例)来处理某个指定的请求。首先咱们得明确几点;
映射器的作用就是联系一个父容器与他的若干个子容器,一个父容器可以有若干个映射器,为什么?因为有这样可以支持不同的协议。
例如一个映射器用来支持http协议,另一个映射器支持https协议(话说,http与https有什么区别,我就说一点,那个s代表security,安全,采取了另一种形式的保密措施,一般银行,证券交易所用https)
Mapper接口如下,我们这节使用的是其实现类,SimpleContextMapper类
package org.apache.catalina; public interface Mapper { public Container getContainer(); public void setContainer(Container container); public String getProtocol(); public void setProtocol(String protocol); public Container map(Request request, boolean update); }
各个方法的名字都起的很好,大家应该可以见名知意。
下面是这一节的uml类图
通过说明的uml图,大家可以看到我们熟悉的SimpleContext"含有"一个SimpleContextMapper,现在我们看看代码
public class SimpleContext implements Context, Pipeline { public SimpleContext() { pipeline.setBasic(new SimpleContextValve()); } protected HashMap<String, Container> children = new HashMap<String, Container>(); protected Loader loader = null; protected SimplePipeline pipeline = new SimplePipeline(this); protected HashMap<String, String> servletMappings = new HashMap<String, String>(); protected Mapper mapper = null; protected HashMap<String, Mapper> mappers = new HashMap<String, Mapper>(); private Container parent = null; ...... }
现在我来说说这个几个属性;
mapper这是一个Mapper类型的是属性,如果一个容器只有一个映射器的话,那么就默认是它;如果一个容器有若干个映射器(以应对不同的网络协议例如http与https)那么mapper就置为空;
mappers这是hashmap类型的,里面放置容器的若干个映射器,以映射器支持的协议作为key;
servletMapping 也是hashmap,里面存放的是一个个映射路径与子容器的映射关系;例如如果访问uri为/servletA,就对应servletA这个servlet;
childen又是一个hashmap,里面存放了servletA这个名字对于的子容器(在这里就是Wrapper)
测试类如下;
public final class Bootstrap2 { @SuppressWarnings("deprecation") public static void main(String[] args) { HttpConnector connector = new HttpConnector(); Wrapper wrapper1 = new SimpleWrapper(); wrapper1.setName("Primitive"); 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"); 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(); } } }
我们先看看时序图
我直接从Context容器里的基础阀讲起,就是它SimpleContextValve(上一节的基础阀是SimpleWrapperValve)。基础阀之前的流程与上一节的内容一样,大家参照上一节。
public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException { ..... 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); }
ok我们到SimpleContext的map方法里看看;
public Container map(Request request, boolean update) { //this method is taken from the map method in org.apache.cataline.core.ContainerBase //the findMapper method always returns the default mapper, if any, regardless the //request's protocol Mapper mapper = findMapper(request.getRequest().getProtocol()); if (mapper == null) return (null); // Use this Mapper to perform this mapping return (mapper.map(request, update)); } public Mapper findMapper(String protocol) { // the default mapper will always be returned, if any, // regardless the value of protocol if (mapper != null) return (mapper); else synchronized (mappers) { return ((Mapper) mappers.get(protocol)); } }
findMapper方法总是返回默认的那个映射器(前面我们已经说了,如果容器中只有一个映射器那它就是默认的,如果有多个,那么存储默认映射器的属性为空)如果有多个映射器就到mappers里去按照网络协议找;
找到映射器之后,就简单了
wrapper.invoke(request, response);
这就回到上一节那部分了,调用Wrapper的所有阀,直到基础阀(在这一节里,wrapper的管道里只有基础阀,之前的两个阀,装到了context的管道里),进入wrapper后调用allocate.......
how tomcat works 5 servlet容器 下
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。