Liferay中过滤器的url mapping研究,顺带对java Web规范提点意见-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

Liferay中过滤器的url mapping研究,顺带对java Web规范提点意见

简介:

引入:

在昨天和同事讲解Minifier Filter时候被问住了,因为我们的访问 url是

http://172.29.175.236:8080/platform-In-theme/css/main.css?browserId=firefox&themeId=platformIn_WAR_platformIntheme&minifierType=css&languageId=en_US&b=6100&t=1377246011000


而Minifier Filter定义的url-mapping如下:

125540570.png


这个url带了这么多连七八糟的参数,分明不匹配这个url-pattern嘛(其实更像是*.css*),那么为什么会进入到这个MinifierFilter过滤器呢?我当时被问住了。


问题分析

为了解决这个问题,我今天花了点时间进行了分析,首先肯定,为了判断一个请求是否要经过某个过滤器,肯定有个返回boolean的方法,我们找到了,这个方法是FilterMapping的isMatch()方法:

130019935.png

从调试信息看,当传递到isMatch()方法的时候,这个uri就已经是/css/main.css了,而我们从<filter-mapping>中的<url-pattern>读取url-pattern是*.css时候,

130225606.png

它会去比较uri和url-pattern,这个比较是通过方法:isMatchURLPattern(uri,urlPattern)


因为我们是*.css,所以它匹配urlPattern.startsWith(_STAR_PERIOD)这个分支:

130419428.png

显然,因为/css/main.css满足*.css,所以它必定返回true.



所以,我们问题的焦点是:当我们请求url是http://172.29.175.236:8080/platform-In-theme/css/main.css?browserId=firefox&themeId=platformIn_WAR_platformIntheme&minifierType=css&languageId=en_US&b=6100&t=1377246011000 时候,为什么对应的uri是/css/main.css 呢?


显然,我们很快的找到了从HttpServletRequest到uri的过程封装在InvokerFilter的getURI()方法中:

130705443.png

它会在第204行

调用HttpServletRequestgetRequestURI() 方法获取uri。

查阅官方文档可以看到HttpServletRequestgetRequestURI()方法只获取请求url中从协议名字到查询字符串的部分,所以它会去掉sheme,host,port和后面的查询字符串。

130836464.png

所以当我们请求http://172.29.175.236:8080/platform-In-theme/css/main.css?browserId=firefox&themeId=platformIn_WAR_platformIntheme&minifierType=css&languageId=en_US&b=6100&t=1377246011000时候,

执行完第204行:uri=request.getRequestURI后,返回的uri/platform-In-theme/css/main.css

131006972.png


然后,

再从207行到210行去掉contextPath部分:

131058658.png


所以,在执行第211行子字符串截取之后,就把“/platform-In-theme"这个contextPath从刚才的uri (/platform-In-theme/css/main.css)中去除了,最终的uri 就是我们期望的uri:

131231225.png


总结:

从这里我们可以有以下结论:

(1)在Liferay的过滤器通过url-mapping匹配url时候,它其实比对的不是请求url(包含scheme,host,port,contextpath, uri,queryString),而是请求uri. 这里也顺便吐槽下java web规范,我觉得对于<filter-pattern>的<url-pattern>命名很不合理,应该叫<uri-pattern>,因为如果叫<url-pattern>的话,应该表明配置url的模式,但是实际比较的确是uri,所以会让人误解,这也是昨天我被问住的原因。如果叫<uri-pattern>的话,那么大家一定会吧uri和这个模式匹配,这样结果就对了。

(2)Liferay中的uri和java web规范中的uri还不完全一样。在java web协议中,uri只是吧scheme,host,port和queryString去掉,所以说,java web协议中的uri=contextPath+后面的path,而在Liferay中的uri,还必须把contextPath部分去掉。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1285073,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章
最新文章
相关文章