Struts框架一度很流行,现在还有很多开发者使用Struts,因为处理遗留代码和投资方面的原因,有更多的开发者已经开始转向使用基于组件的框架。JSF是最受欢迎的组件框架之一,因为JSF是JCP的一部分,而且得到很多厂商支持。JSF 2.0即将发布,不过本文要讨论的是另外两个基于组件框架:Wicket 1.5和Tapestry 5。 很快,Apache基金会将会发布两个有趣的框架新的版本:Wicket 1.5和Tapestry 5。很多人会问,这两个哪个更好?下面我们将在同一平台上对它们做比较。 1.Build Tool 对于很多开发者来说,build tool不是特别重要,但是这是值得考虑的因素之一。Wicket 1.5和Tapestry 5都使用maven作为build tool,这个它们没有区别。 2.Configuration 配置 Wicket 1.5和Tapestry 5都是采用xml,必须要配置的文件是web.xml。其他的,还需要配置xml设置页面调用的action等。这两个框架都认为开发框架应该负责生成URL和页面渲染的顺序,而不是让开发者在xml配置告诉框架如何做。 Wicket的web.xml 1 2 wicket 3 4 org.springframework.web.context.ContextLoaderListener 5 6 7 contextConfigLocation 8 classpath:applicationContext.xml 9 10 11 12 wicket 13 org.apache.wicket.protocol.http.WicketFilter 14 15 applicationClassName 16 agilist.lab.WicketApplication 17 18 19 20 21 wicket 22 /* 23 24 25 如上显示,大多数配置在Java class:WicketApplication中,WicketApplication是一个用来定义你的web应用的java class。 下面是WicketApplication的部分代码: 1 public class WicketApplication extends WebApplication{ 2 public WicketApplication(){} 3 4 public void init(){ 5 super.init(); 6 } 7 8 public Class getHomePage() { 9 return HomePage.class; 10 } 11 } WicketApplication扩展了WebApplication,后者用来通过HTTP协议调用页面。在getHomePage()中返回index.html Tapestry 5 下面看看Tapestry 5的配置,和Wicket类似,唯一必须要配置的文件是web.xml。 1 2 tapestry5 3 4 tapestry.app-package 5 agilist.lab 6 7 8 app 9 org.apache.tapestry5.TapestryFilter 10 11 12 app 13 /* 14 15 在web.xml中,你告诉tapestry到哪里去找到你的页面,组件和mixins。在配置中,你的页面,组件和mixins应该在以下目录中: * Components: agilist.lab.components * Pages: agilist.lab.pages * Mixins: agilist.lab.mixins tapestry 5也拥有配置java class的能力,也类似Wicket。 1 public class AppModule 2 { 3 public static void bind(ServiceBinder binder) 4 { 5 binder.bind(Member.class); 6 } 7 8 public static void contributeApplicationDefaults( 9 MappedConfiguration configuration) 10 { 11 configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en"); 12 configuration.add(SymbolConstants.PRODUCTION_MODE, "false"); 13 } 14 } 这两个框架在配置方面做的都很棒。 3.Controller/Page Class Wicket 和 Tapestry,都是被称为基于 controller in action的框架,两者都是同一的方式来匹配page和class。 Tapestry中,比如我有一个AddMemberPage.java,我的模板名字就是AddMemberPage.html,在Wicket中是用AddMemberPage.tml作为模板。 Wicket: wicket page class: 1 public class AddMemberPage extends BasePage { 2 private static final Logger logger = LoggerFactory.getLogger(AddMemberPage.class); 3 4 private Member member; 5 6 public AddMemberPage() { 7 add(new AddMemberForm("addMemberForm", new CompoundPropertyModel( new Member() ))); 8 } 9 10 public class AddMemberForm extends Form { 11 public AddMemberForm(String id, final CompoundPropertyModel model) { 12 super(id, model); 13 14 member = (Member)model.getObject(); 15 16 add(new TextField("name")); 17 18 add(new Button("save"){ 19 public void onSubmit(){ 20 logger.info("Member name: {}", member.getName()); 21 } 22 }); 23 } 24 } 25 } 这是作为父class的BasePage class: 1 public class BasePage extends WebPage{ 2 public BasePage() { 3 add(new PageLink("homeLink", HomePage.class) 4 .add(new Label("homeLabel", new ResourceModel("home")))); 5 6 add(new BookmarkablePageLink("addMemberLink", AddMemberPage.class) 7 .add( new Label("addMemberLabel", new ResourceModel( "member.add" ) ) ) 8 ); 9 } 10 } Tapestry 5: Tapestry 5 Page class: 1 public class Add { 2 @Inject private Logger logger; 3 4 @Inject @Property @Parameter private Member member; 5 6 void onSelectedFromSave(){ 7 logger.info("Member name: {}", member.getName()); 8 } 9 } 和wicket相同。你必须定义layout class给模板使用。和wicket不同点在于 tapestry 5 模板中使用组件而不是继承。下面是layout class: 1 public class Layout { 2 } 因为layout将作为一个组件,所以必须处于组件包下面。 wicket page class比tapestry 5长很多,不过很有趣,你会发觉wicket中的page class类似swing controller,而tapestry 5和JSF方式更象。 4.模板 Wicket 1.5和Tapestry 5的模板都是使用普通HTML,你不需要调用任何特殊的taglib。 wicket: wicket通过继承方式使用模板,有一个parent父page,作为主要和涉及所有layout的子片断的内容。 1 2 3 4 5 6 7 8 9 10 11 12 Copyright 13 14 15 这和之前的BasePage html layout一致。使用wicket:child标签,就可以让其他子页面继承模板。 1 2 3 4 5 6 7 8 Name 9 10 11 12 13 14 15 16 17 18 19 Tapestry Tapestry5 模板使用的是组件方式: 1 2 3 4 5 6 7 ${message:home} 8 ${message:member.add} 9 10 11 12 Copyright 13 14 15 t:body用来定义什么地方来放置一个组件模板。 使用模板: 1 2 3 4 5 Name 6 7 8 9 10 11 12 13 5.Spring integration 和Spring 集成 Wicket and Tapestry中集成spring都很简单,无缝集成。 wicket: 在init()加一行代码: Java代码 1 addComponentInstantiationListener(new SpringComponentInjector(this)); 类似这样: 1 public class WicketApplication extends WebApplication{ 2 public WicketApplication(){} 3 4 public void init(){ 5 super.init(); 6 7 addComponentInstantiationListener(new SpringComponentInjector(this)); 8 } 9 10 public Class getHomePage() { 11 return HomePage.class; 12 } 13 } 接下来就可以使用spring bean从page class中使用annotating @SpringBean调用: 1 public class AddMemberPage extends BasePage { 2 private static final Logger logger = LoggerFactory.getLogger(AddMemberPage.class); 3 4 private Member member; 5 6 private @SpringBean MemberService service; 7 8 public AddMemberPage() { 9 add(new AddMemberForm("addMemberForm", new CompoundPropertyModel( new Member() ))); 10 } 11 12 public class AddMemberForm extends Form { 13 public AddMemberForm(String id, final CompoundPropertyModel model) { 14 super(id, model); 15 16 member = (Member)model.getObject(); 17 18 add(new TextField("name")); 19 20 add(new Button("save"){ 21 public void onSubmit(){ 22 logger.info("Member name: {}", member.getName()); 23 service.add(member); 24 } 25 }); 26 } 27 } 28 } Tapestry 5 在Tapestry 5中,spring bean被看作tapestry 5的组件,无缝调用和通过tapestry 5 IoC注入。为了集成spring,你需要修改web.xml中一行: 1 2 app 3 org.apache.tapestry5.spring.TapestrySpringFilter 4 接下来就能注入spring bean进入page class通过简单的@Inject annotation: 1 public class Add { 2 @Inject private Logger logger; 3 @Inject private MemberService service; 4 5 @Inject @Property @Parameter private Member member; 6 7 void onSelectedFromSave(){ 8 logger.info("Member name: {}", member.getName()); 9 } 10 } 6.Page unit testing Wicket and Tapestry5的Page unit testing都不需要启动一个servlet容器。 wicket: 不需要锁定一个特殊测试框架,你可以使用JUnit或者TestNG都没问题,因为wicket提供helper class: WicketTester来做page class的Unit testing: 1 public class TestHomePage extends TestCase 2 { 3 private WicketTester tester; 4 5 @Override 6 public void setUp() 7 { 8 tester = new WicketTester(new WicketApplication()); 9 } 10 11 public void testRenderMyPage() 12 { 13 //start and render the test page 14 tester.startPage(HomePage.class); 15 16 //assert rendered page class 17 tester.assertRenderedPage(HomePage.class); 18 } 19 } Tapestry 5 也不需要锁定一个特殊测试框架: 1 public class MyTest extends Assert 2 { 3 @Test 4 public void test1() 5 { 6 String appPackage = "org.example.app"; 7 String appName = "LocaleApp"; 8 PageTester tester = new PageTester(appPackage, appName, "src/main/webapp"); 9 Document doc = tester.renderPage("MyPage"); 10 assertEquals(doc.getElementById("id1").getChildText(), "hello"); 11 } 12 } 以上就是对两个框架的基本比较,比较它们的相同点和不同点。你觉得哪个更好?我认为两者都很酷,只是看你喜欢哪种风格而已。 另外一个问题就是,这两个框架Wicket 和Tapestry 要不要合并?就像struts和webwork一样,因为都是在Apache旗下?你的意见? |
|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )
GMT+8, 2024-9-29 23:32 , Processed in 0.227362 second(s), 12 queries , Gzip On, MemCache On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.