在哪里可以找到用于实现servlet规范的12.1和12.2的JBoss源代码?

时间:2013-08-19 21:40:00

标签: java servlets jboss servlet-3.0

http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-oth-JSpec/servlet-3_0-final-spec.pdf

这将在第12章:将请求映射到Servlet。我查看了JBoss的Maven存储库,虽然spec接口可用,但我似乎无法找到关于servlet url模式匹配的12.1和12.2的底层实现。我有兴趣检查表达式如何映射到另一个项目的规则。

2 个答案:

答案 0 :(得分:3)

我正在考虑Tomcat 7.0.42。以下链接回答指向grepcode.com中的7.0.42源代码。

servlet映射在应用程序启动时解析并在org.apache.tomcat.util.http.mapper.Mapper#addWrapper()内添加Wrapper,其源代码在这里被复制(注意:术语“包装器”在这里基本上代表“映射的servlet”):

360     protected void addWrapper(ContextVersion context, String path,
361             Object wrapper, boolean jspWildCard, boolean resourceOnly) {
362 
363         synchronized (context) {
364             Wrapper newWrapper = new Wrapper();
365             newWrapper.object = wrapper;
366             newWrapper.jspWildCard = jspWildCard;
367             newWrapper.resourceOnly = resourceOnly;
368             if (path.endsWith("/*")) {
369                 // Wildcard wrapper
370                 newWrapper.name = path.substring(0, path.length() - 2);
371                 Wrapper[] oldWrappers = context.wildcardWrappers;
372                 Wrapper[] newWrappers =
373                     new Wrapper[oldWrappers.length + 1];
374                 if (insertMap(oldWrappers, newWrappers, newWrapper)) {
375                     context.wildcardWrappers = newWrappers;
376                     int slashCount = slashCount(newWrapper.name);
377                     if (slashCount > context.nesting) {
378                         context.nesting = slashCount;
379                     }
380                 }
381             } else if (path.startsWith("*.")) {
382                 // Extension wrapper
383                 newWrapper.name = path.substring(2);
384                 Wrapper[] oldWrappers = context.extensionWrappers;
385                 Wrapper[] newWrappers =
386                     new Wrapper[oldWrappers.length + 1];
387                 if (insertMap(oldWrappers, newWrappers, newWrapper)) {
388                     context.extensionWrappers = newWrappers;
389                 }
390             } else if (path.equals("/")) {
391                 // Default wrapper
392                 newWrapper.name = "";
393                 context.defaultWrapper = newWrapper;
394             } else {
395                 // Exact wrapper
396                 if (path.length() == 0) {
397                     // Special case for the Context Root mapping which is
398                     // treated as an exact match
399                     newWrapper.name = "/";
400                 } else {
401                     newWrapper.name = path;
402                 }
403                 Wrapper[] oldWrappers = context.exactWrappers;
404                 Wrapper[] newWrappers =
405                     new Wrapper[oldWrappers.length + 1];
406                 if (insertMap(oldWrappers, newWrappers, newWrapper)) {
407                     context.exactWrappers = newWrappers;
408                 }
409             }
410         }
411     }

在处理传入的HTTP请求时,通过映射查找servlet的所有魔力都始于org.apache.catalina.connector.CoyoteAdapter#postParseRequest()

647        connector.getMapper().map(serverName, decodedURI, version,
648                                  request.getMappingData());
649        request.setContext((Context) request.getMappingData().context);
650        request.setWrapper((Wrapper) request.getMappingData().wrapper);

第647行间接调用org.apache.tomcat.util.http.mapper.Mapper #internalMapWrapper(),这是使用ContextWrapper(本质上是可用的servlet实例)填充当前HTTP请求的映射数据的地方。它只是相当多的代码,我不会在这里复制它,只需单击grepcode链接即可。

然后,第649行和第650行基本上设置了当前请求中的映射ContextWrapperContext保存具体的ServletContext实例,Wrapper保存具体的Servlet实例作为属性org.apache.catalina.core.Wrapper#instance

最后,在调用所有过滤器之后,ApplicationFilterChain将调用servlet的service()方法。


对于我自己的项目OmniFaces JSF utility library,我曾根据WebXml实用程序类中的servlet规范12.1(以相当简化的形式)实现了匹配检查。这些也可能对您有帮助,source code is here,以下相关摘录:

private static boolean isExactMatch(String urlPattern, String url) {
    return url.equals(urlPattern.endsWith("/*") ? urlPattern.substring(0, urlPattern.length() - 2) : urlPattern);
}

private static boolean isPrefixMatch(String urlPattern, String url) {
    return urlPattern.endsWith("/*") ? url.startsWith(urlPattern.substring(0, urlPattern.length() - 2)) : false;
}

private static boolean isSuffixMatch(String urlPattern, String url) {
    return urlPattern.startsWith("*.") ? url.endsWith(urlPattern.substring(1)) : false;
}

答案 1 :(得分:-2)

这取决于模式匹配发生的位置。如果你要让JBoss(真的是Tomcat,Mohammad对此非常正确)处理Web.xml中的所有url映射并仅设置这些映射来处理特定端点上的请求,那么org.apache.naming可能就足够了为了你的目的。

虽然,我可能会跳到NamingContext.java作为开始的好地方。并不是特别令人兴奋它处理它,因为你想象它将使用HashMap作为名称关联(绑定)和HashTable用于对象关联(上下文环境),这仍然是绑定和查找发生的地方。

但是,如果您希望通过前端控制器处理自己的路由,或者想要动态重定向或重新映射,那么Tomcat 8 Servlet 3.0 API文档可能更符合您的要求,它也是您在问题中要求的实施信息。

希望有所帮助。