-
WebX的url生成及URIBroker的问题和解析
前提条件
将WebX应用部署在“/”上,新建一个component名为“happy”。
其中的happy对应的uri对象配置如下:
<uris:uri id="server" requestAware="true" />
<!-- happy --><uris:turbine-uri id="happyModule" exposed="true" extends="server">
<componentPath>/happy</componentPath>
</uris:turbine-uri>
<uris:turbine-content-uri id="happyContent" exposed="true" extends="happyModule" />诡异的现象
当我们分别打开“http://127.0.0.1:8081/happy/”、“http://127.0.0.1:8081/happy/index”和“http://127.0.0.1:8081/happy/index”时,我们发现:
- 在“http://127.0.0.1:8081/happy/”中,$happyModule和$happyContent都被解析为“http://127.0.0.1:8081/happy/happy”,显然,这不是我们想要的结果。
- 在“http://127.0.0.1:8081/happy/index”中, $happyModule和$happyContent都被解析为“http://127.0.0.1:8081/happy/index/happy”,这,跟我们想要的相差更多了
- 在“http://127.0.0.1:8081/happy/index.htm”中, $happyModule和$happyContent都被解析为“http://127.0.0.1:8081/happy”,后面少了个“/”,嗯,还凑合。
我们先来看一下,为啥上面的若干情况如此诡异呢?考虑以下四个URL:
- http://127.0.0.1:8081/happy
- http://127.0.0.1:8081/happy/
- http://127.0.0.1:8081/happy/index
- http://127.0.0.1:8081/happy/index.htm
其实,他们指向的component都是happy,对应的screen都是index。而事实上,WebX也是这么映射到对应的screen的——因为我们能够正常访问页面,而且都是happy下index的内容,对吧。理论上,我们要求WebX对确定的映射内容也返回稳定的渲染结果,而事实却并非如此。为什么呢?我们要深入源代码一探究竟。
深入源码
先简单介绍一下,在com.alibaba.citrus.service.uribroker.uri.URIBroker类中,有一个叫path的数组,里面存放了杠与杠之间的各部分。比如/aaa/bbb/ccc/,那么这个数组存放的是[aaa, bbb, ccc]。此类还有一个叫renderPath()的函数,作用是把path中的各个元素组合起来。如上面的数组会组合成“/aaa/bbb/ccc”。看起来不错,不过少了最后的一道杠。
回到上面的例子,为什么会出现了两次“happy”呢?直接原因,是path数组中存了两个“happy”。根本原因,是因为request.getServletPath()返回了“/happy/”,导致ServletURIBroker类中populateWithRequest()函数误以为当前的servlet是happy。因为在j2ee中,后面处理URI时会把servlet部分切割掉,所以多加了一次“happy”。这是不正确的,因为当前的servlet应该是“/”才对!
而这个getServletPath()函数,则是com.alibaba.citrus.service.requestcontext.rewrite.impl.RewriteRequestContextImpl#RequestWrapper中定义的。
论坛已经有人提出相关的问题:http://www.openwebx.org/forum/showthread.php?tid=91&highlight=servletpath。两年过去,仍旧如故。
解决
相当于写死了URL(参见http://openwebx.org/forum/showthread.php?tid=478和http://hi.baidu.com/epplera/item/5877681cce410e221994ec67)。
方法1:
使用turbine-content-uri,并且增加:<contextPath>Web App的部署目录,一般部署在根目录则填“/”</contextPath>
方法2:
<uris:uri id="server" requestAware="false">
<serverName>127.0.0.1</serverName>
<serverPort>8081</serverPort>
</uris:uri>还凑合的一道杠
为什么说“http://127.0.0.1:8081/happy”还凑合呢?因为,Spring框架中,当我们直接访问“http://127.0.0.1:8081/happy”时,Web服务器发现该网址不存在,于是就返回302跳转到“http://127.0.0.1:8081/happy/”去,所以最后那个是可以正常访问的,虽然跟我们想要的还是差了一道杠(差了网址结尾的“/”)。
不过,一道杠的差别,却不是轻易就能够解决的。话分两头:一方面,想要用turbine-uri在后面加一道简简单单的杠,几乎是不可能的,后文详述原因;另一方面,如果turbine-uri是指向python编写的web app(尤其是用强哥框架,英文名Django框架)的话,就不一定会自动给你补上后面的一道杠,而是冷冰冰地返回一个404错误。
一道杠的距离
这时候,再说一下,WebX中,如果要在uri后面加一道杠,究竟有多难?答案是很难。假设我们分别要生成“http://blog.creke.net/tag/linux/”和“http://blog.creke.net/803.html”,注意后面有道杠。看看下面的配置:
<uris:uri id="crekeServer" requestAware="false" >
<serverName>blog.creke.net</serverName>
</uris:uri><uris:turbine-content-uri id="crekeLink1" exposed="true" extends="crekeServer" >
<contentPath>/tag/linux/</contentPath>
</uris:turbine-content-uri>
<uris:turbine-content-uri id="crekeLink2" exposed="true" extends="crekeServer" >
<componentPath>/tag</componentPath>
<contentPath>/linux/</contentPath>
</uris:turbine-content-uri>
<uris:turbine-uri id="crekeLink3" exposed="true" extends="crekeServer" >
<target>/tag/linux/</target>
</uris:turbine-uri>
<uris:turbine-content-uri id="crekeLink4" exposed="true" extends="crekeServer" >
<contentPath>/803.html</contentPath>
</uris:turbine-content-uri>生成的结果分别是:
- http://blog.creke.net/tag/linux
- http://blog.creke.net/tag/linux
- http://blog.creke.net/tag/linux
- http://blog.creke.net/803.html
根本原因是,uriBroker将任何URL的路径部分都一视同仁地分解为上文所述的path数组。这对于有后缀名的“http://blog.creke.net/803.html”来说无所谓,反正“803.html”是path的一个元素,直接加就对了;但是对于“http://blog.creke.net/tag/linux/”来说,uriBroker并不会记录是否需要补上最后的一道杠,也就是被吞掉了。
总结
在WebX中,如果不想在配置中写死URL前缀,那么除了首页外,总是要加上index.htm来标示默认页面。而如果要生成最后带“/”的URL的字符串,则不要使用URIBroker类。
最后,还是用WebX文档中的一句话来作总结吧:“我并不是说所有的框架都一样好,而是说只要假以时日,所有的框架在发展过程中,必然会积聚好的方面,淘汰坏的方面,从而变得足够好。从这个角度看,的确没有特别明显的理由来选择Webx,但也没有明显的理由不选择Webx。”(via http://openwebx.org/docs/preface.html#d0e76)
《WebX的url生成及URIBroker的问题和解析》已有 4 条评论
最新文章
- EarthLiveSharp中cloudinary的CDN图片缓存自动清理
- WordPress取消英文标点符号自动替换中文标点符号的优雅方法
- 安装aria2及使用yaaw配置WebGUI界面
- Zabbix安装简记
- WordPress垃圾评论大作战
最近评论
- DNS隧道之DNS2TCP使用心得教程》 发表在《
- DNS隧道之DNS2TCP使用心得教程》 发表在《
- SSH隧道与端口转发及内网穿透》 发表在《
- SSH隧道与端口转发及内网穿透》 发表在《
- 64位Windows Server无法启动Tomcat服务的解决办法》 发表在《
标签云
Apache
CCTV
CentOS
Google
JAVA
Linux
MySQL
PHP
PHPmyadmin
rewrite
SSH
StatusNet
wordpress
YY
下载
中国
使用
剧情
动漫
动漫补完计划
动画
博客
域名
安装
影评
恭贺2010
方法
日本
服务器
柯南
死亡笔记
游戏
电影
第10放映室
网站
网络
翻译
腾讯
观后感
规则
视频
解决
设置
评论
配置