浏览器通过AJAX,服务器返回json数据,无刷新的更新视图的这种模式在WEB开发中我已经用了很长时间了,记得最早是08年的时候用的,当时传递JSON数据让我眼前一亮。这种方式是只需要采用工具包将模型序列化成json格式就行,js UI库总能识别这种格式,轻易的生成新的视图片段。
然而时过境迁。这种传递AJAX JSON方式渐渐有了新的问题。
JSON序列化库无法完美的序列化模型对象。序列化库总期望输入一个Object,但实际上前端有可能需要多个Object,这样,你不得不再创建一个序列化专用的Object。 另外,序列化逻辑都很简单,就是将所有对象属性都序列化。尽管JSON Lib 能提供属性过滤,属性格式化等,但扪心自问,远远不如模板渲染功能完善。模板语言提供了丰富的语句和扩展来处理模型对象。另外JSON Lib在序列化对象互相引用,处理的也不好。在模板语言里,这将不存在问题。总而言之,开发人员为了序列化JSON,不得不创建新的视图对象,不得不侵入原有的模型以规定序列化逻辑。以我认为最好的FastJSON工具为列,你能看到各种开发者问的问题(我直接从fastjson论坛行找来最近的帖子).
-在使用 fastjson转map,怎么让map中为null的值等于""呢
-FastJson 1.2.4 日期类型 ISO8601格式序列化问题...
- 建议@JSONType注解添加allows属性,允许设置允许序列化的属性数(作者注:我也建议其他Annotation,用于控制渲染逻辑,事实上,由于缺少语言特性,fastJson会应接不暇这种类似的渲染逻辑建议)
- fastjson 支持escape嘛,防止xss?
2 随着前端技术发展,程序员不再需要easyui,extjs这种前端框架了。因为这种框架不是以视觉为中心的,视觉人员无法左右这种框架。现在更流行的方式还是模板方式,只不过通过前端模板引擎来完成 :输入是JSON和前端模板,输出就是更新后的DOM。 那么问题就来了,这种方式是不是还不如直接后端模板引擎渲染呢?何必费劲的序列化成json,然后,用功能较弱的前端模板引擎来渲染。有点舍近求远的味道。
3 对于有些需要SEO的网站,使用AJAX JSON是致命的问题,因为搜索引擎不能执行javascript,扒到的网页是个空壳子。很不友好。目前也没有太好的办法。据说有一种是仍然采用ajax,但会提供一个不可见的url给搜索引擎以提供正确内容。 另外,据说google搜索引擎有专门的模拟器来模拟javascript执行以获得SEO内容,但属于研发中。
4 对于一个复杂页面,如果多个部分都是用AJAX 请求,这简直是要了Web服务器的命。现在服务器不怕CPU忙,就怕请求多。因此AJAX JSON 这中方式在复杂页面里也是非常不好用的。用的后果就是服务器复杂成倍增加,而页面真正的内容又加载不出来。这同样也没有办法去改善。
吐槽了这么多AJAX+JSON,该说说Beetl是怎么解决的了。
Beetl的解决方法是Ajax+HTML片段,这种方式也不新鲜,但是Beetl有自己独特的解决方法。Beetl引入了新的语法标记#ajax 此语法仅仅标记了一段模板块,后面跟一个id表示ajax片段的名字。如果模板正常渲染视图,模板引擎会忽略#ajax标记,正常渲染模板所有内容。如果渲染的视图带有#id,如 index.html#top10,则模板引擎仅仅渲染#ajax top10标记的内容。如下一个index.html模板:
页面其他内容
.......
%>
#ajax top10:
{
${row.name}
${row.score}
#table>
%>
......
页面其他内容
此模板包含多部分,在此仅仅列出ajax部分,ajax内部是个table标签,或者是其他任何beetl 模板引擎代码都可以。
当用户请求index.html页面的时候,后台controller可能是这样
public String index(){
int page = this.getParameter("top10",0);
this.setAttr("topData",service.getTop10(page ));
//设置其他index需要的数据
this.setAttr("userInfo"...);
this.setAttr("menu"...);
return "/index.html";
}
当用户对top10进行翻页操作的时候,客户端js会发起一个ajax请求到/indexTop10.html,后台controller可能是这样代码
public String indexTop10(){
int page = this.getParameter("top10",0);
this.setAttr("topData",service.getTop10(page ));
return "/index.html#top10";
}
注意到模板渲染的视图是"/index.html#top10",而不是"/index.html",这保证了模板引擎仅仅渲染top10 片段。客户端只需要调用jquery 代码$("#top10").load("/indexTop10.html?page="+xxx) 即可实现无刷新翻页
相对于文章刚开始列举的ajax+json 4大槽点,ajax+beetl都能完美解决。模板的语言功能渲染模板比简单的对象化序列化功能更强,也比前端模板引擎更强。SEO毫无问题,页面受到搜索引擎欢迎。一次渲染不会对服务器造成过多的访问压力。另外,从开发角度来说,开发人员面对的问题也简单多了,能提高了开发效率。
由于Ajax+Beetl 仍然是一种Ajax+HTML的改进,那还是会有AJAX+HTML这种模式的一些些缺点,比如,网络传输数据会增加一些.还有模板渲染性能肯定不如json序列化的性能。如果你的硬件环境很吃紧,你需要慎重考虑这种方式,但一般据我了解,企业应用或者web网站,这些都不是问题。另外一个潜在问题是ajax+json,返回的json数据可以多次在前端处理,比如渲染多个DOM节点,而Ajax+beetl则不行,你只能先渲染一个Dom节点,然后通过js来获取你需要的数据再渲染其他DOM节点,但这种情况也是非常少见的
具体例子可以参考:
http://beetlajax.oschina.mopaas.com/
以及开发者写的文章: http://blog.csdn.net/hiredme/article/details/44219581