我尝试实现一个Tomcat阀(当前使用7.0.55),该阀应拦截到达Tomcat服务的每个请求,而不管连接器和其他原因如何,无论是否存在具有名称匹配的Host或servlet上下文等。
invoke阀门的方法如下:
invoke
public class MyValve extends ValveBase { public void invoke(Request request, Response response) throws IOException, ServletException { LOG.trace("Valve is being invoked"); getNext().invoke(request, response); } }
在开发系统上,在本地进行测试,一切正常。对我的“ localhost” tomcat上任何URI路径的请求都将写入该日志行。在中sever.xml,阀配置在任何Host元素之外:
sever.xml
Host
<Server port="8005" shutdown="SHUTDOWN"> ... <Service name="Catalina"> ... <Engine defaultHost="localhost" name="Catalina"> ... <Realm ... /> <Valve className="a.b.c.MyValve" /> ... <Host ...> </Host> </Engine> </Service> </Server>
现在说在我的系统的hosts文件中,该域test.domain.com映射到127.0.0.1,并且部署了一个名为的上下文some-webapp。
test.domain.com
some-webapp
如上文所述,当我调用时http://localhost:8080/some-webapp/,日志行会得到printet ,这与预期的一样,而当我调用时http://localhost:8080/non-existing-webapp/,也将得到预期的结果,它也会得到打印。 对于域(在server.xml中未配置)test.domain.com也是一样,因此http://test.domain.com/some- webapp/打印日志行和http://test.domain.com/non-existing-webapp。
http://localhost:8080/some-webapp/
http://localhost:8080/non-existing-webapp/
http://test.domain.com/some- webapp/
http://test.domain.com/non-existing-webapp
但这对于我们正在测试的服务器而言并非如此。在此,只有在tomcat对URI的上下文名称是“已知”的情况下才调用Valve,即,对… / some- webapp /的调用将打印日志行,而对… / non-existing-webapp的调用/根本不执行任何操作-根本不调用该阀门。 仍然,tomcat处理该请求,因为在这种情况下发送到客户端的404包含“ Apache Coyote something”作为响应头。
我没有关于如何进一步调试它的想法,尤其是tomcat对管道的“选择”过程或其他任何想法-有什么想法吗?
谢谢!
事实证明,这是由Tomcat的webapps- dir中缺少ROOT目录引起的。我认为Tomcat确实会在非常早的时间点严格过滤掉传入的请求,甚至在任何阀门都无法处理和处理请求之前。 如果没有默认上下文(即没有ROOT-dir),则Tomcat(认为)知道请求non-existing- webapp无法成功,因此甚至不调用Valve。在默认上下文中,Tomcat无法知道请求将发生什么情况,因此阀门有机会拦截请求。
non-existing- webapp