知识库--StandardContextMapper(60)
来源:互联网 发布:淘宝店铺换ip有影响吗 编辑:程序博客网 时间:2024/05/16 05:32
StandardContextMapper
//StandardContextValve首先获取wrapper
For each incoming request, the invoke method of the StandardContext’s pipeline’s basic valve will be called. The basic valve for a StandardContext is repesented by the org.apache.catalina.core.StandardContextValve class. The first thing that StandardContextValve.invoke needs to do is obtain a wrapper that will handle the request.
//valve使用mapper找到对应的wrapper
In tomcat 4, the StandardContextValve instance looks in its contianing StandardContext. The StandardContextValve uses the context’s mapper to find a suitable wrapper. Once it obtains the wrapper, it calls the invoke method of the wrapper. Before delving into what the StandardContextValve does, here presents an introduction to the mapper component.
//父类 add defaultMapper
The ContainerBase class, the parent class of StandardContext, defines the addDefaultMapper method to add a default mapper as follows:
protected void addDefaultMapper(String mapperClass){ //Do we really need a Mapper if(mapperClass == null){ return; } if(mapper.size()>=1) return; //Instantiate and add a default Mapperr try{ Class clazz = Class.forName(mapperClass); Mapper mapper = (Mapper)clazz.newInstance(); mapper.setProtocol("http"); addMapper(mapper); }catch(Exception e){log(...)} }
The StandardContext class calls the addDefaultMapper method from its start method, passing the mapperClass variable:
public synchronized void start() throws LifecycleException{ ... if(ok){ try{ addDefaultMapper(this.mapperClass); }... }}
The StandardContext class defines the mapperClass variable as follows:
private String mapperClass = "org.apache.catalina.core.StandardContextMapper";
//mapper 关联 container
You must then associate a mapper with a container by calling the mapper’s setContainer method, passing the instance of the container. The implementation class of the org.apache.catalina.Mapper interface for StandardContextMapper is org.apache.catalina.core.StandardContextMapper. StandardContextMapper can only be associated with a context, as indicated by its setContainer method.
public void setContainer(Container container){ if(!(container instanceof StandardContext)) throw new IllegalArgumentException(..); context = (StandardContext)container;}
The most important method in a mapper is map, whitch returns a child container to handler an HTTP request. The signature of this method is as follows:
public Container map(Request request, boolean update)
In StandardContextMapper, the map method returns a wrapper that will handle a request. If the appropriate wrapper cannot be found, the map method returns null.
//ContainerBase 调用findMapper寻找 对应协议的mapper
The StandardContextValve instance calls the context’s map method for each incoming HTTP request, passing a org.apache.catalina.Request object. The map method (in the parent class ContainerBase)first obtains a mapper for a particular protocol by calling the findMapper method, and then calling the mapper’s map method.
//select the Mapper we will use Mapper mapper= findMapper(request.getRequest().getProtocol()); if(mapper == null) return null; return (mapper.map(request,update));
The map method in StandardContextMapper first identifies the context-relative URI to be mapped:
String contextPath = ((HttpServletRequest)request.getRequest()).getContextPath(); String requestURI = ((HttpRequest)request).getDecodedRequestURI(); String relativeURI = requestURI.substring(contextPath.length());
//四条规则 map方法获取wrapper
It then attemps to obtain a wrapper by applying four matching rules:
//Apply the standard request URI mapping rules from the specificationWrapper wrapper = null;String servletPath = relativeURI;Stirng pathIfno = null;String name = null;//Rule 1 - Exact Matchif(wrapper == null){ if(!(relativeURI.equals("/"))) name = context.findServletMapping(relativeURI); if(name != null){ wrapper = (Wrapper)context.findChild(name); } if(wrapper != null){ servletPath = relativeURI; pathInfo = null; }}//Rule 2 - Prefix Match 前缀匹配if(wrapper == null){ servletPath = relativeURI; while(true){ name = context.findServletMapping(servletPath + "/*"); if(name != null){ wrapper = (Wrapper)context.findChild(name); } if(wrapper != null){ pathInfo = relativeURI.subString(servletPath.length()); if(pathInfo.length() == 0){ pathInfo = null; } break; } int slash = servletPath.lastIndexOf('/'); if(slash < 0){ break; } servletPath = servletPath.substring(0,slash); }}//Rule 3 - Extension Matchif(wrapper == null){ int slash = relativeURI.lastIndexOf('/'); if(slash >= 0){ String last = relativeURI.substring(slash); int period = last.lastIndexOf('.'); if(period >= 0){ String pattern = "*"+last.substring(period); name = context.findServletMapping(pattern); if(name!=null) wrapper = (Wrapper)context.findChild(name); if(wrapper!=null){ servletPath = relativeURI; pathInfo = null; } } }}//Rule 4 -- Default Matchif(wrapper == null){ name = context.findServletMapping("/"); if(name != null){ wrapper = (Wrapper)context.findChild(name); } if(wrapper != null){ servletPath = relativeURI; pathInfo = null; }}
How does the context have such information as the servlet mappings? recall…
context.addServletMapping("/Primitive","Primitive");context.addServletMapping("/Modern","Modern");
It also adds the wrappers as children of the context:
context.addChild(wrapper1);context.addChild(wrapper2);
Tomcat 5 removed the Mapper interface and its related classes. In fact, the StandardContextValve class’s invoke method obtains the suitable wrapper from the request object:
Wrapper wrapper = request.getWrapper();
which indicates that the mapping information is encapsulated in the request object.
- 知识库--StandardContextMapper(60)
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库
- 知识库--StandardContext + Reloading(60)
- 知识库--StandardContext+backgroundProcess(60)
- 进程知识库
- IT知识库
- IT知识库
- 进程知识库
- VC知识库
- 企业知识库
- 【Leetcode】38. Count and Say
- Docker完全解析 一、Docker简介
- Ubuntu安装Tomcat8
- OP整流电路
- FZU 1036 四塔问题
- 知识库--StandardContextMapper(60)
- 6
- 第一次使用Android Studio时你应该知道的一切配置
- Java做acm所需要的基础知识之基本输入输出问题
- HTTP各版本及区别
- Java基础学习总结——多态(动态绑定)
- 安卓开发中自定义View之onMeasure(),onLayout(),onDraw()讲解(三)
- 第一次使用Android Studio时你应该知道的一切配置(二):新建一个属于自己的工程并安装Genymotion模拟器
- 我的单片机方法论1之概论