日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

How Tomcat Works(八)

發(fā)布時間:2025/4/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 How Tomcat Works(八) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

下面接著分析Context容器,該接口最重要的方法是addWrapper()方法與creatWrapper()方法,添加具體的子容器,這里是Wrapper容器實例

這里要分析的是一個簡單的Context容器,它針對特定的客戶端請求,通過映射器找到要處理該特定請求的子容器實例(Wrapper)

具體流程是,Context容器首先調(diào)用額外的閥,最后調(diào)用基礎(chǔ)閥(這里是SimpleContextValve),在基礎(chǔ)閥里面通過映射器找到要 處理該請求的子容器Wrapper實例,然后再調(diào)用子容器Wrapper實例的各個閥(本示例的Wrapper只有基礎(chǔ)閥)(類似于composte模式 迭代)

下面是SimpleContext類的實現(xiàn),SimpleContext實現(xiàn)org.apache.catalina.Context接口和org.apache.catalina.Pipeline接口

public class SimpleContext implements Context, Pipeline {public SimpleContext() {pipeline.setBasic(new SimpleContextValve());}// 子容器名稱與子容器實例映射protected HashMap children = new HashMap();protected Loader loader = null;protected SimplePipeline pipeline = new SimplePipeline(this);// servlet模式與子容器名稱映射protected HashMap servletMappings = new HashMap();// 映射器protected Mapper mapper = null;// 映射器協(xié)議與映射器實例映射protected HashMap mappers = new HashMap();private Container parent = null;/*** 添加servlet模式與子容器名稱(wrapper)到HashMap servletMappings容器* @param pattern* @param name*/public void addServletMapping(String pattern, String name) {synchronized (servletMappings) {servletMappings.put(pattern, name);}} /*** 根據(jù)servlet模式找到對應(yīng)的子容器名稱(wrapper)(供映射器調(diào)用)* @param pattern* @return*/public String findServletMapping(String pattern) {synchronized (servletMappings) {return ((String) servletMappings.get(pattern));}}/*** 獲取加載器* @return*/public Loader getLoader() {if (loader != null)return (loader);if (parent != null)return (parent.getLoader());return (null);}/*** 設(shè)置加載器* @param loader*/public void setLoader(Loader loader) {this.loader = loader;}/*** 添加子容器實例(wrapper)名稱與子容器實例(wrapper)到HashMap children容器* @param child*/public void addChild(Container child) {child.setParent((Container) this);children.put(child.getName(), child);}/*** 根據(jù)名稱查找子容器實例wrapper(供映射器調(diào)用)* @param name* @return*/public Container findChild(String name) {if (name == null)return (null);synchronized (children) {// Required by post-start changesreturn ((Container) children.get(name));}}/*** 查找子容器數(shù)組* @return*/public Container[] findChildren() {synchronized (children) {Container results[] = new Container[children.size()];return ((Container[]) children.values().toArray(results));}}/*** 添加映射器實例* @param mapper*/public void addMapper(Mapper mapper) {// this method is adopted from addMapper in ContainerBase// the first mapper added becomes the default mappermapper.setContainer((Container) this); // May throw IAEthis.mapper = mapper;synchronized (mappers) {if (mappers.get(mapper.getProtocol()) != null)throw new IllegalArgumentException("addMapper: Protocol '"+ mapper.getProtocol() + "' is not unique");mapper.setContainer((Container) this); // May throw IAE mappers.put(mapper.getProtocol(), mapper);if (mappers.size() == 1)this.mapper = mapper;elsethis.mapper = null;}}/*** 根據(jù)協(xié)議查找映射器實例* @param protocol* @return*/public Mapper findMapper(String protocol) {// the default mapper will always be returned, if any,// regardless the value of protocolif (mapper != null)return (mapper);elsesynchronized (mappers) {return ((Mapper) mappers.get(protocol));}}public Mapper[] findMappers() {return null;}/*** 根據(jù)請求找到子容器實例wrapper (供基礎(chǔ)閥調(diào)用該方法)* @param request* @param update* @return*/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 protocolMapper mapper = findMapper(request.getRequest().getProtocol());if (mapper == null)return (null);// Use this Mapper to perform this mapping// 具體過程 (回調(diào)該對象下面方法)// 根據(jù)request找到處理該請求的子容器wrapper名稱 調(diào)用方法 String findServletMapping(String pattern)// 根據(jù)上面的子容器wrapper名稱找到子容器wrapper 調(diào)用方法 Container findChild(String name)return (mapper.map(request, update));}public void invoke(Request request, Response response) throws IOException,ServletException {pipeline.invoke(request, response);}// method implementations of Pipelinepublic Valve getBasic() {return pipeline.getBasic();}public void setBasic(Valve valve) {pipeline.setBasic(valve);}public synchronized void addValve(Valve valve) {pipeline.addValve(valve);}public Valve[] getValves() {return pipeline.getValves();}public void removeValve(Valve valve) {pipeline.removeValve(valve);}}

下面我們來分析映射器SimpleContextMapper的實現(xiàn)

public class SimpleContextMapper implements Mapper {/*** The Container with which this Mapper is associated.*/private SimpleContext context = null;public Container getContainer() {return (context);}public void setContainer(Container container) {if (!(container instanceof SimpleContext))throw new IllegalArgumentException("Illegal type of container");context = (SimpleContext) container;}public String getProtocol() {return null;}public void setProtocol(String protocol) {}/*** Return the child Container that should be used to process this Request,* based upon its characteristics. If no such child Container can be* identified, return <code>null</code> instead.** @param request Request being processed* @param update Update the Request to reflect the mapping selection?** @exception IllegalArgumentException if the relative portion of the* path cannot be URL decoded*/public Container map(Request request, boolean update) {// Identify the context-relative URI to be mappedString 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 specificationWrapper wrapper = null;String servletPath = relativeURI;String pathInfo = null;String name = context.findServletMapping(relativeURI);if (name != null)wrapper = (Wrapper) context.findChild(name);return (wrapper);} }

映射器SimpleContextMapper最重要的方法是Container map(Request request, boolean update)

即根據(jù)客戶端請求找到對應(yīng)的子容器實例wrapper,里面關(guān)鍵代碼是回調(diào)context容器實例的方法(持有對SimpleContext實例的引用)

接下里分析基礎(chǔ)閥的關(guān)鍵代碼(管道持有對基礎(chǔ)閥的引用)

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 typesif (!(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-INFHttpServletRequest 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 RequestWrapper 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);} public Container getContainer() {return container;}public void setContainer(Container container) {this.container = container;}private void badRequest(String requestURI, HttpServletResponse response) {try {response.sendError(HttpServletResponse.SC_BAD_REQUEST, requestURI);}catch (IllegalStateException e) {;}catch (IOException e) {;}}private void notFound(String requestURI, HttpServletResponse response) {try {response.sendError(HttpServletResponse.SC_NOT_FOUND, requestURI);}catch (IllegalStateException e) {;}catch (IOException e) {;}}}

基礎(chǔ)閥持有對Context容器實例(SimpleContext)的引用,在它的關(guān)鍵方法void invoke(Request request, Response response, ValveContext valveContext)里面,先調(diào)用Context容器實例的Container map(Request request, boolean update)方法獲取子容器實例wrapper,最后調(diào)用子容器實例wrapper的invoke(Request request, Response response)方法

至于管道類SimplePipeline與上文相同,此處不再描述

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創(chuàng)?

轉(zhuǎn)載請注明出處 博客園 刺猬的溫馴?

本人郵箱: chenying998179#163.com (#改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3235730.html

轉(zhuǎn)載于:https://www.cnblogs.com/chenying99/p/3235730.html

總結(jié)

以上是生活随笔為你收集整理的How Tomcat Works(八)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。