request获取容器过程
- 获取容器过程
- 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获取容器过程的更多相关文章
- spring mvc DispatcherServlet详解之二---request通过Controller获取ModelAndView过程
整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet通过request获取控制器Controller的过程,现在来讲解DispatcherServletDisp ...
- Spring拦截器中通过request获取到该请求对应Controller中的method对象
背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...
- request获取各种路径总结、页面跳转总结。
页面跳转总结 JSP中response.sendRedirect()与request.getRequestDispatcher().forward(request,response)这两个对象都可以使 ...
- request 获取服务根目录地址
这是常用的request获取服务地址的常用方式. 源请求服务地址:http://localhost/api-server/1/forum/thread/hot_topic?sex=1 String p ...
- jsp Request获取url信息的各种方法比较
从Request对象中可以获取各种路径信息,以下例子: 假设请求的页面是index.jsp,项目是WebDemo,则在index.jsp中获取有关request对象的各种路径信息如下 String p ...
- request 获取各种路径
从request获取各种路径总结 request.getRealPath("url"); // 虚拟目录映射为实际目录 request.getRealPath("./&q ...
- request 获取请求参数
/** * 根据request获取请求的用户参数 * @return * @return */ protected <T> T getParamConvertEntity(Class cl ...
- Ffmpeg解析media容器过程/ ffmpeg 源代码简单分析 : av_read_frame()
ffmpeg 源代码简单分析 : av_read_frame() http://blog.csdn.net/leixiaohua1020/article/details/12678577 ffmpeg ...
- Request 获取Url
1.获取页面,HttpContext.Current.Request也是Request //获取当前页面url string myurl = HttpContext.Current.Request.U ...
随机推荐
- Tido c++树状数组知识讲解(转载)
树状数组可以用来动态计算前缀和,可以随时进行更新 而普通的前缀和只是静态的
- 管理分布式session的四种方式。
应用服务器的高可用架构设计最为理想的是服务无状态,但实际上业务总会有状态的,以session记录用户信息的例子来讲,未登入时,服务器没有记入用户信息的session访问网站都是以游客方式访问的,账号密 ...
- 03- 基本的SQL语句介绍
01 库的操作新增库create database db1 charset utf8; # 由于在my.ini中已经配置了字符集,所以,charset utf8可以不写 查库# 查看当前创建的数据库s ...
- 用Docker搭建LNMP
程序员经常会说的一句话:在我的机器上是正常的,肯定是你的机器有问题.因此,Docker诞生了,它把应用所需要的一切东西都打包,从而可以很方便地进行部署. Docker 的主要用途,目前有三大类: 提供 ...
- Spring_two
Spring_two 基于注解的IOC配置 准备工作(参考上一篇) ); 接口的实现类AccountDaoImpl.java修改 /** * 账户的持久层实现类 */ @Repository(&quo ...
- Protoc Buffer 优化传输大小的一个细节
Protoc Buffer 是我们比较常用的序列化框架,Protocol Buffer 序列化后的占空间小,传输高效,可以在不同编程语言以及平台之间传输.今天这篇文章主要介绍 Protocol Buf ...
- 迁移桌面程序到MS Store(9)——APPX With Desktop Extension
在<迁移桌面程序到MS Store(8)——通过APPX下载Win32Component>中我们讨论了通过APPX来下载Service部分的安装包.但是纯UWP的客户端并不能自动运行下载的 ...
- Storm 学习之路(五)—— Storm编程模型详解
一.简介 下图为Strom的运行流程图,在开发Storm流处理程序时,我们需要采用内置或自定义实现spout(数据源)和bolt(处理单元),并通过TopologyBuilder将它们之间进行关联,形 ...
- PATB 1018. 锤子剪刀布
时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图 ...
- mysql 正确清理binlog日志的两种方法
前言: MySQL中的binlog日志记录了数据库中数据的变动,便于对数据的基于时间点和基于位置的恢复,但是binlog也会日渐增大,占用很大的磁盘空间,因此,要对binlog使用正确安全的方法清理掉 ...