jetty的servlet请求路由与ContextHandlerColleection的实现(二)

2014-11-24 08:54:09 · 作者: · 浏览: 2
lArgumentException ("Illegal context spec:"+contextPath);
if(!contextPath.startsWith("/")) //如果不是/开头的,那么给它加上
contextPath='/'+contextPath;
if (contextPath.length()>1) {
if (contextPath.endsWith("/")) //表示一个路径下的所有,那么就为其添加*
contextPath+="*";
else if (!contextPath.endsWith("/*"))
contextPath+="/*"; //反正都是要变成/*
}
//也就是最后的contextPath都要变成类似于:/manager/* 类型的
Object contexts=contextMap.get(contextPath); //这个path对应的所有contexts,这里可以理解为其实一个数组
String[] vhosts=handler.getVirtualHosts(); //获取 虚拟主机
if (vhosts!=null && vhosts.length>0) { //如果有虚拟主机名字
Map hosts;
if (contexts instanceof Map) {
hosts=(Map)contexts;
} else {
hosts=new HashMap();
hosts.put("*",contexts);
contextMap.put(contextPath, hosts);
}
for (int j=0;j
{
String vhost=vhosts[j];
contexts=hosts.get(vhost);
contexts=LazyList.add(contexts,branches[b]);
hosts.put(vhost,contexts);
}
} else if (contexts instanceof Map) {
Map hosts=(Map)contexts;
contexts=hosts.get("*");
contexts= LazyList.add(contexts, branches[b]);
hosts.put("*",contexts);
} else {
contexts= LazyList.add(contexts, branches[b]); //为这个contexts添加handler
contextMap.put(contextPath, contexts); //将这个paht与这个context对应起来,里面会进行前缀和后缀的处理
}
}
}
_contextMap=contextMap; //让当前的contextMap指向刚刚创建的pathMap
}
代码还挺长的。。。其实主要要做的事情如下:
(1)遍历当前所有的handler,其实也就是contextHandler
(2)预处理他们的path,一般情况下例如加入我们的工程为manager,那么部署在jetty,默认的path将是/manager,这里的预处理是将其变成/manager/*这个样子。。。
(3)将其放到pathMap里面去。。。让pathMap来处理对应关系。。。有前缀,后缀匹配什么的。。这里还涉及到虚拟主机名什么的。。就不细看了。。
最后我们再来看看另外一个很重要的方法,handle方法,ContextHandlerCollection的handle方法的用处就是将http请求分发给对应的contextHandler来处理。。。
来看他的定义吧:
[java]
//这里的target是没有经过处理的,直接就是最原始的url后面的那些,例如/manager/public/aa.jpg,也就是包括了前面的contextPath
//这个函数用于将http请求路由给匹配的contextHandler来处理
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException {
Handler[] handlers = getHandlers(); //获得当前所有的handler
if (handlers==null || handlers.length==0)
return;
Request base_request = HttpConnection.getCurrentConnection().getRequest(); //获取当前的http请求,前面会将它保存在线程变量中
// data structure which maps a request to a context
// each match is called in turn until the request is handled
// { context path =>
// { virtual host => context }
// }
PathMap map = _contextMap; //当前的context的map
if (map!=null && target!=null && target.startsWith("/")) {
//这里获取所有匹配的context
Object contexts = map.getLazyMatches(target); //获取匹配的context
for (int i=0; i
// then, match against the virtualhost of each context
Map.Entry entry = (Map.Entry)LazyList.get(contex