1. 获取容器过程
  2.  
  3. CoyoteAdapter.postParseRequest(org.apache.coyote.Request req, Request request,
  4. org.apache.coyote.Response res, Response response)
  5.  
  6. connector.getService().getMapper().map(serverName, decodedURI,
  7. version, request.getMappingData());
  8.  
  9. Mapper.map
  10.  
  11. public void map(MessageBytes host, MessageBytes uri, String version,
  12. MappingData mappingData) throws IOException {
  13.  
  14. if (host.isNull()) {
  15. host.getCharChunk().append(defaultHostName);
  16. }
  17. host.toChars();
  18. uri.toChars();
  19. internalMap(host.getCharChunk(), uri.getCharChunk(), version,
  20. mappingData);
  21. }
  22.  
  23. Mapper.internalMap
  24.  
  25. private final void internalMap(CharChunk host, CharChunk uri,
  26. String version, MappingData mappingData) throws IOException {
  27.  
  28. if (mappingData.host != null) {
  29. // The legacy code (dating down at least to Tomcat 4.1) just
  30. // skipped all mapping work in this case. That behaviour has a risk
  31. // of returning an inconsistent result.
  32. // I do not see a valid use case for it.
  33. throw new AssertionError();
  34. }
  35.  
  36. uri.setLimit(-1);
  37. // Virtual host mapping
  38. MappedHost[] hosts = this.hosts;
  39. //根据host域名精确查找host
  40. MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
  41. if (mappedHost == null) {
  42. // Note: Internally, the Mapper does not use the leading * on a
  43. // wildcard host. This is to allow this shortcut.
  44. //*.apache.org --> .apache.org,通过这个去查找
  45. int firstDot = host.indexOf('.');
  46. if (firstDot > -1) {
  47. int offset = host.getOffset();
  48. try {
  49. host.setOffset(firstDot + offset);
  50. mappedHost = exactFindIgnoreCase(hosts, host);
  51. } finally {
  52. // Make absolutely sure this gets reset
  53. host.setOffset(offset);
  54. }
  55. }
  56. if (mappedHost == null) {
  57. mappedHost = defaultHost;//如果没有找到就使用默认host
  58. if (mappedHost == null) {
  59. return;
  60. }
  61. }
  62. }
  63. mappingData.host = mappedHost.object;
  64.  
  65. // Context mapping 前缀匹配
  66. ContextList contextList = mappedHost.contextList;
  67. MappedContext[] contexts = contextList.contexts;
  68. int pos = find(contexts, uri);
  69. if (pos == -1) {
  70. return;
  71. }
  72.  
  73. int lastSlash = -1;
  74. int uriEnd = uri.getEnd();
  75. int length = -1;
  76. boolean found = false;
  77. MappedContext context = null;
  78. while (pos >= 0) {
  79. context = contexts[pos];
  80. if (uri.startsWith(context.name)) {
  81. //如果长度一样直接表示找到匹配的对象
  82. length = context.name.length();
  83. if (uri.getLength() == length) {
  84. found = true;
  85. break;
  86. } else if (uri.startsWithIgnoreCase("/", length)) {
  87. found = true;
  88. break;
  89. }
  90. }
  91. //查找最后一个/的位置(匹配最长的路径),然后从开始到这个点进行匹配
  92. if (lastSlash == -1) {
  93. lastSlash = nthSlash(uri, contextList.nesting + 1);
  94. } else {
  95. lastSlash = lastSlash(uri);
  96. }
  97. uri.setEnd(lastSlash);
  98. pos = find(contexts, uri);
  99. }
  100. uri.setEnd(uriEnd);
  101.  
  102. if (!found) {
  103. //如果没有找打,使用默认的context,如果连默认的都没有直接返回null
  104. if (contexts[0].name.equals("")) {
  105. context = contexts[0];
  106. } else {
  107. context = null;
  108. }
  109. }
  110. if (context == null) {
  111. return;
  112. }
  113.  
  114. mappingData.contextPath.setString(context.name);
  115.  
  116. ContextVersion contextVersion = null;
  117. ContextVersion[] contextVersions = context.versions;
  118. final int versionCount = contextVersions.length;
  119. if (versionCount > 1) {
  120. Context[] contextObjects = new Context[contextVersions.length];
  121. for (int i = 0; i < contextObjects.length; i++) {
  122. contextObjects[i] = contextVersions[i].object;
  123. }
  124. mappingData.contexts = contextObjects;
  125. if (version != null) {
  126. //精确查找版本
  127. contextVersion = exactFind(contextVersions, version);
  128. }
  129. }
  130. if (contextVersion == null) {
  131. // Return the latest version
  132. // The versions array is known to contain at least one element
  133. contextVersion = contextVersions[versionCount - 1];
  134. }
  135. mappingData.context = contextVersion.object;
  136. mappingData.contextSlashCount = contextVersion.slashCount;
  137.  
  138. // Wrapper mapping
  139. if (!contextVersion.isPaused()) {
  140. internalMapWrapper(contextVersion, uri, mappingData);
  141. }
  142.  
  143. }
  144.  
  145. Mapper.internalMapWrapper
  146.  
  147. private final void internalMapWrapper(ContextVersion contextVersion,
  148. CharChunk path,
  149. MappingData mappingData) throws IOException {
  150.  
  151. int pathOffset = path.getOffset();
  152. int pathEnd = path.getEnd();
  153. boolean noServletPath = false;
  154.  
  155. int length = contextVersion.path.length();
  156. if (length == (pathEnd - pathOffset)) {
  157. noServletPath = true;//如果请求路径和context路径一样长,那么就表示没有servletPath,这种路径一般是使用默认的index页面
  158. }
  159. int servletPath = pathOffset + length;
  160. path.setOffset(servletPath);//设置servlet路径,比如localhost:8080/test/index --> servlet路径为index,那么偏移地址为index第一个字符的下标
  161.  
  162. // Rule 1 -- Exact Match 精确匹配
  163. MappedWrapper[] exactWrappers = contextVersion.exactWrappers;
  164. internalMapExactWrapper(exactWrappers, path, mappingData);
  165.  
  166. // Rule 2 -- Prefix Match 前缀匹配,这里的匹配和context的匹配方式一样
  167. boolean checkJspWelcomeFiles = false;
  168. MappedWrapper[] wildcardWrappers = contextVersion.wildcardWrappers;
  169. if (mappingData.wrapper == null) {
  170. internalMapWildcardWrapper(wildcardWrappers, contextVersion.nesting,
  171. path, mappingData);
  172. if (mappingData.wrapper != null && mappingData.jspWildCard) {
  173. char[] buf = path.getBuffer();
  174. if (buf[pathEnd - 1] == '/') {
  175. /*
  176. * Path ending in '/' was mapped to JSP servlet based on
  177. * wildcard match (e.g., as specified in url-pattern of a
  178. * jsp-property-group.
  179. * Force the context's welcome files, which are interpreted
  180. * as JSP files (since they match the url-pattern), to be
  181. * considered. See Bugzilla 27664.
  182. */
  183. mappingData.wrapper = null;
  184. checkJspWelcomeFiles = true;
  185. } else {
  186. // See Bugzilla 27704
  187. mappingData.wrapperPath.setChars(buf, path.getStart(),
  188. path.getLength());
  189. mappingData.pathInfo.recycle();
  190. }
  191. }
  192. }
  193.  
  194. if(mappingData.wrapper == null && noServletPath &&
  195. contextVersion.object.getMapperContextRootRedirectEnabled()) {
  196. // The path is empty, redirect to "/"
  197. path.append('/');
  198. pathEnd = path.getEnd();
  199. mappingData.redirectPath.setChars
  200. (path.getBuffer(), pathOffset, pathEnd - pathOffset);
  201. path.setEnd(pathEnd - 1);
  202. return;
  203. }
  204.  
  205. // Rule 3 -- Extension Match
  206. MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;
  207. if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
  208. internalMapExtensionWrapper(extensionWrappers, path, mappingData,
  209. true);
  210. }
  211.  
  212. // Rule 4 -- Welcome resources processing for servlets
  213. if (mappingData.wrapper == null) {
  214. boolean checkWelcomeFiles = checkJspWelcomeFiles;
  215. if (!checkWelcomeFiles) {
  216. char[] buf = path.getBuffer();
  217. checkWelcomeFiles = (buf[pathEnd - 1] == '/');
  218. }
  219. if (checkWelcomeFiles) {
  220. for (int i = 0; (i < contextVersion.welcomeResources.length)
  221. && (mappingData.wrapper == null); i++) {
  222. path.setOffset(pathOffset);
  223. path.setEnd(pathEnd);
  224. path.append(contextVersion.welcomeResources[i], 0,
  225. contextVersion.welcomeResources[i].length());
  226. path.setOffset(servletPath);
  227.  
  228. // Rule 4a -- Welcome resources processing for exact macth
  229. internalMapExactWrapper(exactWrappers, path, mappingData);
  230.  
  231. // Rule 4b -- Welcome resources processing for prefix match
  232. if (mappingData.wrapper == null) {
  233. internalMapWildcardWrapper
  234. (wildcardWrappers, contextVersion.nesting,
  235. path, mappingData);
  236. }
  237.  
  238. // Rule 4c -- Welcome resources processing
  239. // for physical folder
  240. if (mappingData.wrapper == null
  241. && contextVersion.resources != null) {
  242. String pathStr = path.toString();
  243. WebResource file =
  244. contextVersion.resources.getResource(pathStr);
  245. if (file != null && file.isFile()) {
  246. internalMapExtensionWrapper(extensionWrappers, path,
  247. mappingData, true);
  248. if (mappingData.wrapper == null
  249. && contextVersion.defaultWrapper != null) {
  250. mappingData.wrapper =
  251. contextVersion.defaultWrapper.object;
  252. mappingData.requestPath.setChars
  253. (path.getBuffer(), path.getStart(),
  254. path.getLength());
  255. mappingData.wrapperPath.setChars
  256. (path.getBuffer(), path.getStart(),
  257. path.getLength());
  258. mappingData.requestPath.setString(pathStr);
  259. mappingData.wrapperPath.setString(pathStr);
  260. }
  261. }
  262. }
  263. }
  264.  
  265. path.setOffset(servletPath);
  266. path.setEnd(pathEnd);
  267. }
  268.  
  269. }
  270.  
  271. /* welcome file processing - take 2
  272. * Now that we have looked for welcome files with a physical
  273. * backing, now look for an extension mapping listed
  274. * but may not have a physical backing to it. This is for
  275. * the case of index.jsf, index.do, etc.
  276. * A watered down version of rule 4
  277. */
  278. if (mappingData.wrapper == null) {
  279. boolean checkWelcomeFiles = checkJspWelcomeFiles;
  280. if (!checkWelcomeFiles) {
  281. char[] buf = path.getBuffer();
  282. checkWelcomeFiles = (buf[pathEnd - 1] == '/');
  283. }
  284. if (checkWelcomeFiles) {
  285. for (int i = 0; (i < contextVersion.welcomeResources.length)
  286. && (mappingData.wrapper == null); i++) {
  287. path.setOffset(pathOffset);
  288. path.setEnd(pathEnd);
  289. path.append(contextVersion.welcomeResources[i], 0,
  290. contextVersion.welcomeResources[i].length());
  291. path.setOffset(servletPath);
  292. internalMapExtensionWrapper(extensionWrappers, path,
  293. mappingData, false);
  294. }
  295.  
  296. path.setOffset(servletPath);
  297. path.setEnd(pathEnd);
  298. }
  299. }
  300.  
  301. // Rule 7 -- Default servlet
  302. if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
  303. if (contextVersion.defaultWrapper != null) {
  304. mappingData.wrapper = contextVersion.defaultWrapper.object;
  305. mappingData.requestPath.setChars
  306. (path.getBuffer(), path.getStart(), path.getLength());
  307. mappingData.wrapperPath.setChars
  308. (path.getBuffer(), path.getStart(), path.getLength());
  309. mappingData.matchType = MappingMatch.DEFAULT;
  310. }
  311. // Redirection to a folder
  312. char[] buf = path.getBuffer();
  313. if (contextVersion.resources != null && buf[pathEnd -1 ] != '/') {
  314. String pathStr = path.toString();
  315. WebResource file;
  316. // Handle context root
  317. if (pathStr.length() == 0) {
  318. file = contextVersion.resources.getResource("/");
  319. } else {
  320. file = contextVersion.resources.getResource(pathStr);
  321. }
  322. if (file != null && file.isDirectory() &&
  323. contextVersion.object.getMapperDirectoryRedirectEnabled()) {
  324. // Note: this mutates the path: do not do any processing
  325. // after this (since we set the redirectPath, there
  326. // shouldn't be any)
  327. path.setOffset(pathOffset);
  328. path.append('/');
  329. mappingData.redirectPath.setChars
  330. (path.getBuffer(), path.getStart(), path.getLength());
  331. } else {
  332. mappingData.requestPath.setString(pathStr);
  333. mappingData.wrapperPath.setString(pathStr);
  334. }
  335. }
  336. }
  337.  
  338. path.setOffset(pathOffset);
  339. path.setEnd(pathEnd);
  340. }

request获取容器过程的更多相关文章

  1. spring mvc DispatcherServlet详解之二---request通过Controller获取ModelAndView过程

    整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet通过request获取控制器Controller的过程,现在来讲解DispatcherServletDisp ...

  2. Spring拦截器中通过request获取到该请求对应Controller中的method对象

    背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...

  3. request获取各种路径总结、页面跳转总结。

    页面跳转总结 JSP中response.sendRedirect()与request.getRequestDispatcher().forward(request,response)这两个对象都可以使 ...

  4. request 获取服务根目录地址

    这是常用的request获取服务地址的常用方式. 源请求服务地址:http://localhost/api-server/1/forum/thread/hot_topic?sex=1 String p ...

  5. jsp Request获取url信息的各种方法比较

    从Request对象中可以获取各种路径信息,以下例子: 假设请求的页面是index.jsp,项目是WebDemo,则在index.jsp中获取有关request对象的各种路径信息如下 String p ...

  6. request 获取各种路径

    从request获取各种路径总结 request.getRealPath("url"); // 虚拟目录映射为实际目录 request.getRealPath("./&q ...

  7. request 获取请求参数

    /** * 根据request获取请求的用户参数 * @return * @return */ protected <T> T getParamConvertEntity(Class cl ...

  8. Ffmpeg解析media容器过程/ ffmpeg 源代码简单分析 : av_read_frame()

    ffmpeg 源代码简单分析 : av_read_frame() http://blog.csdn.net/leixiaohua1020/article/details/12678577 ffmpeg ...

  9. Request 获取Url

    1.获取页面,HttpContext.Current.Request也是Request //获取当前页面url string myurl = HttpContext.Current.Request.U ...

随机推荐

  1. Tido c++树状数组知识讲解(转载)

    树状数组可以用来动态计算前缀和,可以随时进行更新 而普通的前缀和只是静态的         

  2. 管理分布式session的四种方式。

    应用服务器的高可用架构设计最为理想的是服务无状态,但实际上业务总会有状态的,以session记录用户信息的例子来讲,未登入时,服务器没有记入用户信息的session访问网站都是以游客方式访问的,账号密 ...

  3. 03- 基本的SQL语句介绍

    01 库的操作新增库create database db1 charset utf8; # 由于在my.ini中已经配置了字符集,所以,charset utf8可以不写 查库# 查看当前创建的数据库s ...

  4. 用Docker搭建LNMP

    程序员经常会说的一句话:在我的机器上是正常的,肯定是你的机器有问题.因此,Docker诞生了,它把应用所需要的一切东西都打包,从而可以很方便地进行部署. Docker 的主要用途,目前有三大类: 提供 ...

  5. Spring_two

    Spring_two 基于注解的IOC配置 准备工作(参考上一篇) ); 接口的实现类AccountDaoImpl.java修改 /** * 账户的持久层实现类 */ @Repository(&quo ...

  6. Protoc Buffer 优化传输大小的一个细节

    Protoc Buffer 是我们比较常用的序列化框架,Protocol Buffer 序列化后的占空间小,传输高效,可以在不同编程语言以及平台之间传输.今天这篇文章主要介绍 Protocol Buf ...

  7. 迁移桌面程序到MS Store(9)——APPX With Desktop Extension

    在<迁移桌面程序到MS Store(8)——通过APPX下载Win32Component>中我们讨论了通过APPX来下载Service部分的安装包.但是纯UWP的客户端并不能自动运行下载的 ...

  8. Storm 学习之路(五)—— Storm编程模型详解

    一.简介 下图为Strom的运行流程图,在开发Storm流处理程序时,我们需要采用内置或自定义实现spout(数据源)和bolt(处理单元),并通过TopologyBuilder将它们之间进行关联,形 ...

  9. PATB 1018. 锤子剪刀布

    时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图 ...

  10. mysql 正确清理binlog日志的两种方法

    前言: MySQL中的binlog日志记录了数据库中数据的变动,便于对数据的基于时间点和基于位置的恢复,但是binlog也会日渐增大,占用很大的磁盘空间,因此,要对binlog使用正确安全的方法清理掉 ...