获取容器过程

CoyoteAdapter.postParseRequest(org.apache.coyote.Request req, Request request,
org.apache.coyote.Response res, Response response) connector.getService().getMapper().map(serverName, decodedURI,
version, request.getMappingData()); Mapper.map public void map(MessageBytes host, MessageBytes uri, String version,
MappingData mappingData) throws IOException { if (host.isNull()) {
host.getCharChunk().append(defaultHostName);
}
host.toChars();
uri.toChars();
internalMap(host.getCharChunk(), uri.getCharChunk(), version,
mappingData);
} Mapper.internalMap private final void internalMap(CharChunk host, CharChunk uri,
String version, MappingData mappingData) throws IOException { if (mappingData.host != null) {
// The legacy code (dating down at least to Tomcat 4.1) just
// skipped all mapping work in this case. That behaviour has a risk
// of returning an inconsistent result.
// I do not see a valid use case for it.
throw new AssertionError();
} uri.setLimit(-1);
// Virtual host mapping
MappedHost[] hosts = this.hosts;
//根据host域名精确查找host
MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
if (mappedHost == null) {
// Note: Internally, the Mapper does not use the leading * on a
// wildcard host. This is to allow this shortcut.
//*.apache.org --> .apache.org,通过这个去查找
int firstDot = host.indexOf('.');
if (firstDot > -1) {
int offset = host.getOffset();
try {
host.setOffset(firstDot + offset);
mappedHost = exactFindIgnoreCase(hosts, host);
} finally {
// Make absolutely sure this gets reset
host.setOffset(offset);
}
}
if (mappedHost == null) {
mappedHost = defaultHost;//如果没有找到就使用默认host
if (mappedHost == null) {
return;
}
}
}
mappingData.host = mappedHost.object; // Context mapping 前缀匹配
ContextList contextList = mappedHost.contextList;
MappedContext[] contexts = contextList.contexts;
int pos = find(contexts, uri);
if (pos == -1) {
return;
} int lastSlash = -1;
int uriEnd = uri.getEnd();
int length = -1;
boolean found = false;
MappedContext context = null;
while (pos >= 0) {
context = contexts[pos];
if (uri.startsWith(context.name)) {
//如果长度一样直接表示找到匹配的对象
length = context.name.length();
if (uri.getLength() == length) {
found = true;
break;
} else if (uri.startsWithIgnoreCase("/", length)) {
found = true;
break;
}
}
//查找最后一个/的位置(匹配最长的路径),然后从开始到这个点进行匹配
if (lastSlash == -1) {
lastSlash = nthSlash(uri, contextList.nesting + 1);
} else {
lastSlash = lastSlash(uri);
}
uri.setEnd(lastSlash);
pos = find(contexts, uri);
}
uri.setEnd(uriEnd); if (!found) {
//如果没有找打,使用默认的context,如果连默认的都没有直接返回null
if (contexts[0].name.equals("")) {
context = contexts[0];
} else {
context = null;
}
}
if (context == null) {
return;
} mappingData.contextPath.setString(context.name); ContextVersion contextVersion = null;
ContextVersion[] contextVersions = context.versions;
final int versionCount = contextVersions.length;
if (versionCount > 1) {
Context[] contextObjects = new Context[contextVersions.length];
for (int i = 0; i < contextObjects.length; i++) {
contextObjects[i] = contextVersions[i].object;
}
mappingData.contexts = contextObjects;
if (version != null) {
//精确查找版本
contextVersion = exactFind(contextVersions, version);
}
}
if (contextVersion == null) {
// Return the latest version
// The versions array is known to contain at least one element
contextVersion = contextVersions[versionCount - 1];
}
mappingData.context = contextVersion.object;
mappingData.contextSlashCount = contextVersion.slashCount; // Wrapper mapping
if (!contextVersion.isPaused()) {
internalMapWrapper(contextVersion, uri, mappingData);
} } Mapper.internalMapWrapper private final void internalMapWrapper(ContextVersion contextVersion,
CharChunk path,
MappingData mappingData) throws IOException { int pathOffset = path.getOffset();
int pathEnd = path.getEnd();
boolean noServletPath = false; int length = contextVersion.path.length();
if (length == (pathEnd - pathOffset)) {
noServletPath = true;//如果请求路径和context路径一样长,那么就表示没有servletPath,这种路径一般是使用默认的index页面
}
int servletPath = pathOffset + length;
path.setOffset(servletPath);//设置servlet路径,比如localhost:8080/test/index --> servlet路径为index,那么偏移地址为index第一个字符的下标 // Rule 1 -- Exact Match 精确匹配
MappedWrapper[] exactWrappers = contextVersion.exactWrappers;
internalMapExactWrapper(exactWrappers, path, mappingData); // Rule 2 -- Prefix Match 前缀匹配,这里的匹配和context的匹配方式一样
boolean checkJspWelcomeFiles = false;
MappedWrapper[] wildcardWrappers = contextVersion.wildcardWrappers;
if (mappingData.wrapper == null) {
internalMapWildcardWrapper(wildcardWrappers, contextVersion.nesting,
path, mappingData);
if (mappingData.wrapper != null && mappingData.jspWildCard) {
char[] buf = path.getBuffer();
if (buf[pathEnd - 1] == '/') {
/*
* Path ending in '/' was mapped to JSP servlet based on
* wildcard match (e.g., as specified in url-pattern of a
* jsp-property-group.
* Force the context's welcome files, which are interpreted
* as JSP files (since they match the url-pattern), to be
* considered. See Bugzilla 27664.
*/
mappingData.wrapper = null;
checkJspWelcomeFiles = true;
} else {
// See Bugzilla 27704
mappingData.wrapperPath.setChars(buf, path.getStart(),
path.getLength());
mappingData.pathInfo.recycle();
}
}
} if(mappingData.wrapper == null && noServletPath &&
contextVersion.object.getMapperContextRootRedirectEnabled()) {
// The path is empty, redirect to "/"
path.append('/');
pathEnd = path.getEnd();
mappingData.redirectPath.setChars
(path.getBuffer(), pathOffset, pathEnd - pathOffset);
path.setEnd(pathEnd - 1);
return;
} // Rule 3 -- Extension Match
MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;
if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
internalMapExtensionWrapper(extensionWrappers, path, mappingData,
true);
} // Rule 4 -- Welcome resources processing for servlets
if (mappingData.wrapper == null) {
boolean checkWelcomeFiles = checkJspWelcomeFiles;
if (!checkWelcomeFiles) {
char[] buf = path.getBuffer();
checkWelcomeFiles = (buf[pathEnd - 1] == '/');
}
if (checkWelcomeFiles) {
for (int i = 0; (i < contextVersion.welcomeResources.length)
&& (mappingData.wrapper == null); i++) {
path.setOffset(pathOffset);
path.setEnd(pathEnd);
path.append(contextVersion.welcomeResources[i], 0,
contextVersion.welcomeResources[i].length());
path.setOffset(servletPath); // Rule 4a -- Welcome resources processing for exact macth
internalMapExactWrapper(exactWrappers, path, mappingData); // Rule 4b -- Welcome resources processing for prefix match
if (mappingData.wrapper == null) {
internalMapWildcardWrapper
(wildcardWrappers, contextVersion.nesting,
path, mappingData);
} // Rule 4c -- Welcome resources processing
// for physical folder
if (mappingData.wrapper == null
&& contextVersion.resources != null) {
String pathStr = path.toString();
WebResource file =
contextVersion.resources.getResource(pathStr);
if (file != null && file.isFile()) {
internalMapExtensionWrapper(extensionWrappers, path,
mappingData, true);
if (mappingData.wrapper == null
&& contextVersion.defaultWrapper != null) {
mappingData.wrapper =
contextVersion.defaultWrapper.object;
mappingData.requestPath.setChars
(path.getBuffer(), path.getStart(),
path.getLength());
mappingData.wrapperPath.setChars
(path.getBuffer(), path.getStart(),
path.getLength());
mappingData.requestPath.setString(pathStr);
mappingData.wrapperPath.setString(pathStr);
}
}
}
} path.setOffset(servletPath);
path.setEnd(pathEnd);
} } /* welcome file processing - take 2
* Now that we have looked for welcome files with a physical
* backing, now look for an extension mapping listed
* but may not have a physical backing to it. This is for
* the case of index.jsf, index.do, etc.
* A watered down version of rule 4
*/
if (mappingData.wrapper == null) {
boolean checkWelcomeFiles = checkJspWelcomeFiles;
if (!checkWelcomeFiles) {
char[] buf = path.getBuffer();
checkWelcomeFiles = (buf[pathEnd - 1] == '/');
}
if (checkWelcomeFiles) {
for (int i = 0; (i < contextVersion.welcomeResources.length)
&& (mappingData.wrapper == null); i++) {
path.setOffset(pathOffset);
path.setEnd(pathEnd);
path.append(contextVersion.welcomeResources[i], 0,
contextVersion.welcomeResources[i].length());
path.setOffset(servletPath);
internalMapExtensionWrapper(extensionWrappers, path,
mappingData, false);
} path.setOffset(servletPath);
path.setEnd(pathEnd);
}
} // Rule 7 -- Default servlet
if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
if (contextVersion.defaultWrapper != null) {
mappingData.wrapper = contextVersion.defaultWrapper.object;
mappingData.requestPath.setChars
(path.getBuffer(), path.getStart(), path.getLength());
mappingData.wrapperPath.setChars
(path.getBuffer(), path.getStart(), path.getLength());
mappingData.matchType = MappingMatch.DEFAULT;
}
// Redirection to a folder
char[] buf = path.getBuffer();
if (contextVersion.resources != null && buf[pathEnd -1 ] != '/') {
String pathStr = path.toString();
WebResource file;
// Handle context root
if (pathStr.length() == 0) {
file = contextVersion.resources.getResource("/");
} else {
file = contextVersion.resources.getResource(pathStr);
}
if (file != null && file.isDirectory() &&
contextVersion.object.getMapperDirectoryRedirectEnabled()) {
// Note: this mutates the path: do not do any processing
// after this (since we set the redirectPath, there
// shouldn't be any)
path.setOffset(pathOffset);
path.append('/');
mappingData.redirectPath.setChars
(path.getBuffer(), path.getStart(), path.getLength());
} else {
mappingData.requestPath.setString(pathStr);
mappingData.wrapperPath.setString(pathStr);
}
}
} path.setOffset(pathOffset);
path.setEnd(pathEnd);
}

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. 高性能嵌入式核心板新标杆!米尔推出基于NXP i.MX8M处理器的MYC-JX8MX核心板

    随着嵌入式及物联网技术的飞速发展,高性能计算的嵌入式板卡已经成为智能产品的基础硬件平台.为响应行业应用和满足客户需求,米尔电子推出基于NXP公司i.MX8M系列芯片的开发平台MYD-JX8MX系列开发 ...

  2. JDK JRE JVM 分别是什么

    JDK: Java Development Kit Java 开发工具包 JRE: Java Runtime Enviroment Java 运行时环境 JVM: Java Virtual Machi ...

  3. 27 background

    先来讲讲颜色表示法 一共有三种:单词.rgb表示法.十六进制表示法 rgb:红色 绿色 蓝色 三原色 光学显示器,每个像素都是由三原色的发光原件组成的,靠明亮度不同调成不同的颜色的. 用逗号隔开,r. ...

  4. vuex分模块4

    Vuex下Store的模块化拆分实践 https://segmentfault.com/a/1190000007667542 vue.js vuex 猫切 2016年12月02日发布 赞  |   1 ...

  5. git的基本指令

    更多详情请看廖雪峰官方网站 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 1.删 ...

  6. JS中闭包的介绍

    闭包的概念 闭包就是能够读取其他函数内部变量的函数. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascri ...

  7. Selenium Grid分布式测试环境搭建

    Selenium Grid简介 Selenium Grid实际上是基于Selenium RC的,而所谓的分布式结构就是由一个hub节点和若干个node代理节点组成.Hub用来管理各个代理节点的注册信息 ...

  8. 简单的 自动生成 二维码 PHP 方法

    方法一:<style type="text/css">.eweima{    width:200px; height:200px; margin:auto;}</ ...

  9. Python入门基础(3 下)

    接着讲列表里面的一些操作吧 列表元素访问与计数 1.统计指定元素在列表中出现的次数使用count(),这就不必细说了,直接看代码,需要记住的是括号里面放的是元素 list = [1,5,5,5,5,8 ...

  10. 使用PowerShell比较本地文本文件与Web上的文本文件是否相同

    使用PowerShell比较本地文本文件是否相同通常有两种方式:1.通过Get-FileHash这个命令,比较两个文件的哈希是否相同:2.通过Compare-Object这个命令,逐行比较两个文件的内 ...