需求
已知一串url(GET/POST请求均可),在没有源代码的线上环境(只能够使用容器内置的Arthas),根据该url得到调用url的类路径。
步骤
1、随便找一串url:
https://googleads.g.doubleclick.net/pagead/adview?ai=CQ
2、进入Arthas,执行命令:
watch org.springframework.web.servlet.DispatcherServlet getHandler '{params,returnObj,throwExp}' 'params[0].getRequestURI.contains("pagead/adview")' -n 5 -x 3
完成。
原理分析
该命令其实就是监控了:DispatcherServlet getHandler 这个方法:
该方法的第一个入参,有一个 getRequestURI 方法
该URI其实就是你的请求路径。
随后追加一个Arthas的条件表达式:
'params[0].getRequestURI.contains("pagead/adview")'
补充:Arthas watch 条件表达式:
条件其实就是就是:OGNL 表达式(请求路径包含pagead/adview):
.contains("pagead/adview")'
最终效果就是:凡是符合条件表达式过滤的参数(pagead/adview)的入参、返回值、可能的报错('{params,returnObj,throwExp}’),都会被打印出来。
但是我们最终想要的其实就是只是返回值(HandlerExecutionChain)的调用链路:
如下图所示,的确得到了被Spring容器管理的调用链路。其中就包括了我们的Controller (最终类路径):
(马赛克是公司信息,防止泄密)
看到这里,大概应该明白了。
后记
这个案例说明了读Spring源码的重要性,如果不深入源码的学习,这个巧妙的方法根本就想不出来…
扩展一下,我们是不是可以通过对MyBatis源码的了解,来对可能执行的SQL进行一个过滤呢?
看来源码的学习还是不能落下啊!