1. 方便的Renderer
在Asta4D中,所有的渲染逻辑都通过一个叫做Renderer的类来声明,Renderer类提供了丰富的接口来帮助用户实现渲染逻辑:
Renderer render = new GoThroughRenderer();
render.add("#someIdForInt", 12345);
render.add("#someIdForLong", 12345L);
render.add("#someIdForBool", true);
render.add("#someIdForStr", "a str");
render.add("#someIdForNull", (Object) null);
render.add("#someIdForClear", Clear);
Element newChild = ElementUtil.parseAsSingle("<div></div>");
render.add("#someIdForElementSetter", new ChildReplacer(newChild));
render.add("#someIdForElement", ElementUtil.parseAsSingle("<div>eee</div>"));
render.add("#someIdForRenderer", Renderer.create("#value", "value"));
对于List数据,也可以轻松的渲染:
Renderer render = new GoThroughRenderer();
render.add("#someIdForInt", Arrays.asList(123, 456, 789));
render.add("#someIdForLong", Arrays.asList(123L, 456L, 789L));
render.add("#someIdForBool", Arrays.asList(true, true, false));
render.add("#someIdForStr", Arrays.asList("str1", "str2", "str3"));
Element newChild1 = ElementUtil.parseAsSingle("<div>1</div>");
Element newChild2 = ElementUtil.parseAsSingle("<div>2</div>");
render.add("#someIdForElementSetter", Arrays.asList(new ChildReplacer(newChild1), new ChildReplacer(newChild2)));
render.add("#someIdForElement", Arrays.asList(newChild1, newChild2));
render.add("#someIdForRenderer", Arrays.asList(123, 456, 789), new RowConvertor<Integer, Renderer>() {
@Override
public Renderer convert(int rowIndex, Integer obj) {
return Renderer.create("#id", "id-" + obj).add("#otherId", "otherId-" + obj);
}
});
Dom元素的属性也可以简单的操作:
render.add("#id", "+class", "yyy");
render.add("#id", "-class", "zzz");
render.add("#id", "+class", "xxx");
render.add("#id", "value", "hg");
render.add("#id", "href", null);
render.add("#X", "value", new Date(123456L));
2. 安全的Renderer
从前面的示例代码已经可以看到,除了引用"ElementUtil.parseAsSingle"从字符串自行构建Dom元素以外,其他所有对DOM的操作都是通过Renderer代理的,事实上,所有被Renderer代理的渲染操作都会被强制转义,这意味着如果你的代码中没有调用“ElementUtil.parseAsSingle”的话,你的系统对Cross-Site是天然免疫的,你不需要考虑用户是否在你的系统中提交了非法字符,所有的数据,在被render到页面的时候,都会被强制HTML转义。另一方面,从我们的实践经验来看,需要调“ElementUtil.parseAsSingle”来自行构建HTML的情况是非常少见的,因此,你只需要看管好你为数不多的“ElementUtil.parseAsSingle”调用,你就可以跟Cross-site漏洞说bye-bye了。
3. 可测试的渲染逻辑
Web页面的测试一直是个老大难问题,selenium是常见技术,用来测试页面的渲染是否正确。对于Asta4D来说,可测试的Renderer使得我们可以减少至少一半selenium测试用例而代之以简单的junit测试。
仔细考察前面的示例代码,所有的渲染逻辑都保存在Renderer类中,因此,很自然的,我们只需要对snippet方法返回的Renderer实例进行测试就足以确认大部分的渲染逻辑是否正确了:
RendererTester tester = RendererTester.forRenderer(render);
Assert.assertEquals(tester.get("#someIdForInt"), 12345);
Assert.assertEquals(tester.get("#someIdForLong"), 12345L);
Assert.assertEquals(tester.get("#someIdForBool"), true);
Assert.assertEquals(tester.get("#someIdForStr"), "a str");
Assert.assertEquals(tester.get("#someIdForNull"), null);
Assert.assertEquals(tester.get("#someIdForClear"), Clear);