Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008

5,421 views

Published on

Full source code of the demo application is downloadble from http://www.alphacsp.com/Events/Web-Frameworks-2008/Demos/wicket-demo.zip

Published in: Technology, Education
  • Be the first to comment

Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008

  1. 1. Apache Wicket – keep it simple! Baruch Sadogursky Consultant & Architect, AlphaCSP 2 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  2. 2. Agenda • Introduction • Framework features • Summary 3 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  3. 3. Introduction 4 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  4. 4. Intro::Wicket • “Wicket” means “gate” • Cricket • Small door inside a big gate • Wicket W. Warrick • Star Wars character • Why “Wicket”? • Unique, memorable, easy and not taken • “Wik-it” • Lightweight wicket in immovable J2EE gate 5 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  5. 5. Intro::Apache Wicket • Component–oriented • Open Source • Write HTML (HTML style) • Write Java (Swing style) • Tie them together through IDs 6 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  6. 6. Intro::Hello, World! 1 public class HelloWorld extends WebPage { 2 public HelloWorld() { 3 add(new Label(quot;messagequot;, quot;Hello, World!quot;)); 4 } 5 } + 1 <html> 2 <body> 3 <h1 wicket:id=quot;messagequot;>Hello, World!</h1> 4 </body> 5 </html> = 1 <html> 2 <body> 3 <h1 wicket:id=quot;messagequot;>Hello, World!</h1> 4 </body> 5 </html> 7 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  7. 7. Intro::Looks Familiar? Wicket: 1 public class HelloWorld extends WebPage { 2 public HelloWorld() { 3 add(new Label(quot;messagequot;, quot;Hello, World!quot;)); 4 } 5 } Swing: 1 public class HelloWorld extends JFrame { 2 public HelloWorld() { 3 add(new Label(quot;Hello, World!quot;)); 4 } 5 } 8 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  8. 8. Intro::History Mar-04 Jonathan Locke envisioned and originated Wicket Jun-05 Mar-06 Jul-07 Jan-08 Jun-08 May-05 Wicket 1.0 final Wicket 1.2 released Apache Wicket Wicket 1.3 released Wicket 1.4 m2 JavaOne presentation Apr-04 Jul-04 Oct-04 Jan-05 Apr-05 Jul-05 Oct-05 Jan-06 Apr-06 Jul-06 Oct-06 Jan-07 Apr-07 Jul-07 Oct-07 Jan-08 Apr-08 Mar-04 Jun-08 9 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  9. 9. Intro::Wicket Hype 10 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  10. 10. Intro::Concepts – Component • Building block of the application • Renders itself • Receives events • More than 220 components in Wicket core & Wicket extensions • Easily extendable (customizable) 11 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  11. 11. Intro:: Concepts – Components Swing Wicket awt.Component Component awt.Container WebComponent MarkupContainer awt.Window JContainer Label Page WebMarkupContainer awt.Frame JComponent WebPage Panel Link JFrame JPanel JLabel JButton 12 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  12. 12. Intro::Concepts – Model • No property binding in Java (for now) • Wraps Object, which component renders • Basic models for single object • Property models for properties • EL like expressions • Exactly as Swing Models 1 private IColumn[] getTableColumns() { 2 List<IColumn> columns = new ArrayList<IColumn>(); 3 columns.add(new PropertyColumn(new ResourceModel(quot;namequot;), quot;namequot;, quot;namequot;)); 4 columns.add(new PropertyColumn(new ResourceModel(quot;department.namequot;), quot;department.namequot;)); 5 columns.add(new TextFieldColumn(new ResourceModel(quot;emailquot;), quot;emailquot;)); 6 return columns.toArray(new IColumn[columns.size()]); 7 } 1 public LoginForm(MarkupContainer parent) { 2 super(quot;loginFormquot;, new CompoundPropertyModel(new User())); 3 parent.add(this); 4 add(new TextField(quot;usernamequot;).setRequired(true)); 5 PasswordTextField passwordTextField = new PasswordTextField(quot;passwordquot;); 6 passwordTextField.setRequired(true); 7 add(passwordTextField); 8 … 9 } 13 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  13. 13. Intro::Concepts – Behavior • Plugin to the component • Gets component lifecycle events and can react by changing the generated HTML • Example • SimpleAttributeModifier changes HTML tag attributes on render 14 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  14. 14. Intro::Concepts • Application • Configure and init • Example later • Session • Strongly typed HTTP session wrapper • RequestCycle • Represents the processing of a request • Tells RequestCycleProcessor what to do • How to handle events • How to generate response 15 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  15. 15. Wicket Features Review 16 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  16. 16. Features::Configuration • No Wicket XML files • Convention over configuration • Configuration done in Java • Spring integration • Just enable injecting interceptor 1 @SpringBean 1 protected void init() { 2 private UserService userService; 2 super.init(); 3 addComponentInstantiationListener(new SpringComponentInjector(this)); 4 getResourceSettings().setThrowExceptionOnMissingResource(true); 5 mountBookmarkablePage(quot;hello_world.htmlquot;, HelloWorld.class); 6 } 7 8 @Override 9 public Class getHomePage() { 10 return SearchPage.class; 11 } 17 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  17. 17. Features::View Technology • Valid XHTML • No custom markup (almost) • wicket:id attribute • The only mandatory one • <wicket:message/> resource bundle lookup • See I18N 18 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  18. 18. Features::View Technology • Reuse HTML as it was Java • <wicket:child/> • <wicket:extend/> • <wicket:panel/> 1 <!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict//ENquot; 2 quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtdquot;> 3 <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> 4 <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xmlns:wicket=quot;http://wicket.apache.org/quot;> 5 <head> 6 … 11 </head> 12 <body> 13 <wicket:child/> 14 </body> 15 </html> 1 <wicket:extend> 2 <div align=quot;rightquot; class=quot;headerquot; wicket:id=quot;welcomePanelquot;></div> 3 <div class=quot;phoneBookquot; align=quot;centerquot; wicket:id=quot;searchPanelquot;></div> 4 <div class=quot;phoneBookquot; align=quot;centerquot; wicket:id=quot;resultsPanelquot;></div> 5 </wicket:extend> 19 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  19. 19. Features::View Technology • Reuse HTML as it was Java • <wicket:child/> • <wicket:extend/> • <wicket:panel/> 1 <wicket:extend> 2 <div align=quot;rightquot; class=quot;headerquot; wicket:id=quot;welcomePanelquot;></div> 3 <div class=quot;phoneBookquot; align=quot;centerquot; wicket:id=quot;searchPanelquot;></div> 4 <div class=quot;phoneBookquot; align=quot;centerquot; wicket:id=quot;resultsPanelquot;></div> 5 </wicket:extend> 1 <wicket:panel> 2 <table> 3 <tr> 4 <td class=quot;headerquot;><wicket:message key=quot;userquot;/>: <span wicket:id=quot;usernamequot;></span></td> 5 <td class=quot;headerSeperatorquot;>|</td> 6 <td class=quot;headerquot;><a href=quot;#quot; wicket:id=quot;logoutquot;><wicket:message key=quot;logoutquot;/></a></td> 7 </tr> 8 </table> 9 </wicket:panel> 20 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  20. 20. Features::Page Flow • Inside onSubmit (buttons, links and forms) • setResponsePage(SomePage.class); • setResponsePage(somePage); 1 @Override 2 protected void onSubmit() { 3 User credentials = (User) this.getModelObject(); 4 WicketSession session = WicketSession.get(); 5 User loggedInUser = userService.login(credentials); 6 if (loggedInUser != null) { 7 session.setUser(loggedInUser); 8 setResponsePage(SearchPage.class); 9 } else { 10 this.error(quot;Sorry, …quot;); 11 setModelObject(new User()); 12 } 13 } 21 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  21. 21. Features::Form Binding • Form is a component • So, it is backed up with model 1 private SearchForm(MarkupContainer parent) { 2 super(quot;searchFormquot;, new CompoundPropertyModel(new Contact())); 3 parent.add(this); 4 add(new TextField(quot;namequot;)); 5 TextField emailTextField = new TextField(quot;emailquot;); 6 emailTextField.add(EmailAddressValidator.getInstance()); 7 add(emailTextField); 8 … 9 } 22 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  22. 22. Features::Table Sorting • Headers should be added to table • Property expression is optionally passed when constructing Column • If passed – the header will be clickable 1 private static class SortablePagedDataTable extends DataTable { 2 private SortablePagedDataTable(String id, IColumn[] tableColumns, 3 ContactsListDataProvider contacts, int rowsPerPage) { 4 super(id, tableColumns, contacts, rowsPerPage); 5 addTopToolbar(new AjaxFallbackHeadersToolbar(this, contacts)); 6 addBottomToolbar(new AjaxNavigationToolbar(this)); 7 } 8 } 1 private IColumn[] getTableColumns() { 2 List<IColumn> columns = new ArrayList<IColumn>(); 3 columns.add(new PropertyColumn(new ResourceModel(quot;namequot;), quot;namequot;, quot;namequot;)); 4 columns.add(new PropertyColumn(new ResourceModel(quot;department.namequot;), quot;department.namequot;)); 5 columns.add(new TextFieldColumn(new ResourceModel(quot;emailquot;), quot;emailquot;)); 6 return columns.toArray(new IColumn[columns.size()]); 7 } 8 23 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  23. 23. Features::Table Sorting • You generate the displayed data • So, you are in charge of actual sorting • Property expression and sort direction is provided 1 public class ContactsListDataProvider extends SortableDataProvider { 2 … 3 public Iterator<Contact> iterator(int first, int count) { 4 List<Contact> sublist = data.subList(first, first + count); 5 SortParam sort = getSort(); 6 if (sort != null && quot;namequot;.equals(sort.getProperty())) { 7 Collections.sort(sublist); 8 if (!sort.isAscending()) { 9 Collections.reverse(sublist); 10 } 11 } 12 return sublist.iterator(); 13 } 24 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  24. 24. Features::Pagination • Navigation toolbar should be added to table (top or bottom) • Rows per page count is passed in the constructor 1 private static class SortablePagedDataTable extends DataTable { 2 private SortablePagedDataTable(String id, IColumn[] tableColumns, 3 ContactsListDataProvider contacts, int rowsPerPage) { 4 super(id, tableColumns, contacts, rowsPerPage); 5 addTopToolbar(new AjaxFallbackHeadersToolbar(this, contacts)); 6 addBottomToolbar(new AjaxNavigationToolbar(this)); 7 } 8 } 1 public ResultsPanel(ContactsListDataProvider contactsDataProvider) { 2 super(quot;resultsPanelquot;); 3 DataTable contactsTable = new SortablePagedDataTable(quot;contactsTablequot;, 4 getTableColumns(), contactsDataProvider, 10); 5 add(contactsTable); 6 } 25 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  25. 25. Features::Pagination • You generate the displayed data • So, you are in charge of actual sublisting • First and count are provided 1 public class ContactsListDataProvider extends SortableDataProvider { 2 … 3 public Iterator<Contact> iterator(int first, int count) { 4 List<Contact> sublist = data.subList(first, first + count); 5 SortParam sort = getSort(); 6 if (sort != null && quot;namequot;.equals(sort.getProperty())) { 7 Collections.sort(sublist); 8 if (!sort.isAscending()) { 9 Collections.reverse(sublist); 10 } 11 } 12 return sublist.iterator(); 13 } 26 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  26. 26. Features::Validations (Server) • “Required” validation – just say • Validation errors added to their own <div> (css it at will) 1 public LoginForm(MarkupContainer parent) { 2 super(quot;loginFormquot;, new CompoundPropertyModel(new User())); 3 parent.add(this); 4 add(new TextField(quot;usernamequot;).setRequired(true)); 5 PasswordTextField passwordTextField = new PasswordTextField(quot;passwordquot;); 6 passwordTextField.setRequired(true); 7 add(passwordTextField); 8 FeedbackPanel feedbackPanel = new FeedbackPanel(quot;feedbackquot;); 9 feedbackPanel.setEscapeModelStrings(false); 10 add(feedbackPanel); 11 } 1 <tr> 2 <td colspan=quot;2quot; class=quot;feedbackquot; wicket:id=quot;feedbackquot;/> 3 </tr> 27 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  27. 27. Features::Validations (Server) • Other validations – add Validators to the components • 24 ready validators in wicket-core and wicket-extensions 1 private SearchForm(MarkupContainer parent) { 2 super(quot;searchFormquot;, new CompoundPropertyModel(new Contact())); 3 parent.add(this); 4 add(new TextField(quot;namequot;)); 5 TextField emailTextField = new TextField(quot;emailquot;); 6 emailTextField.add(EmailAddressValidator.getInstance()); 7 … 12 } 28 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  28. 28. Features::Validations (Client) • Server validations are must • Target of client validation – provide earlier feedback to the user • Client validations should be copy of Java code in JS • No automatic JS port for server-side validations (only Google can?) 29 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  29. 29. Features::Validations (Client) • Solution – call server-side validations in AJAX • Same experience for the user • Slower on slow connections 1 private SearchForm(MarkupContainer parent) { 2 super(quot;searchFormquot;, new CompoundPropertyModel(new Contact())); 3 parent.add(this); 4 add(new TextField(quot;namequot;)); 5 TextField emailTextField = new TextField(quot;emailquot;); 6 emailTextField.add(EmailAddressValidator.getInstance()); 7 … 8 AjaxFormValidatingBehavior.addToAllFormComponents(this, quot;onblurquot;); 9 } 30 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  30. 30. Features::AJAX • Use AJAX components instead of non-AJAX ones • Add components to be refreshed 1 private SearchForm(MarkupContainer parent) { 2 super(quot;searchFormquot;, new CompoundPropertyModel(new Contact())); 3 parent.add(this); 4 … 12 add(new AjaxButton(quot;submitquot;, this){ 13 14 @Override 15 protected void onSubmit(AjaxRequestTarget target, Form form) { 16 Contact exampleContact = (Contact) SearchForm.this.getModelObject(); 17 List<Contact> contacts = companyService.findContactsByExample(exampleContact); 18 contactsDataProvider.setData(contacts); 19 ResultsPanel resultsPanel = ((SearchPage) getPage()).getResultsPanel(); 20 target.addComponent(resultsPanel); 21 } 22 }); 23 AjaxFormValidatingBehavior.addToAllFormComponents(this, quot;onblurquot;); 24 } 31 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  31. 31. Features::AJAX • JS is generated using Dojo and Script.aculo.us • Automatic fallback to non-js components 1 <script type=quot;text/javascriptquot; 2 src=quot;resources/org.apache.wicket.markup.html.WicketEventReference/wicket-event.jsquot;> 3 </script> 4 <script type=quot;text/javascriptquot; 5 src=quot;resources/org.apache.wicket.ajax.WicketAjaxReference/wicket-ajax.jsquot;> 6 </script> 7 <script type=quot;text/javascriptquot; 8 src=quot;resources/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/wicket-ajax-debug.jsquot;> 9 </script> 10 <script type=quot;text/javascriptquot; 11 id=quot;wicket-ajax-debug-enablequot;><!--/*--><![CDATA[/*><!--*/ 12 wicketAjaxDebugEnable = true; 13 /*-->]]>*/</script> 14 <script type=quot;text/javascriptquot; 15 src=quot;resources/org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteBehavior/wicket-autocomplete.jsquot;> 16 </script> 17 <script type=quot;text/javascriptquot;><!--/*--><![CDATA[/*><!--*/ 18 Wicket.Event.add(window, quot;domreadyquot;, function() { 19 new Wicket.AutoComplete('department2', 20 '?wicket:interface=:2:searchPanel:searchForm:department::IActivePageBehaviorListener:1:&wicket:ignoreIfNotActive=true', 21 false); 22 }); 23 /*-->]]>*/</script> 32 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  32. 32. Features::AJAX • Great debug utility 33 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  33. 33. Features::Error Handling – Dev • Very self-explanatory error pages 34 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  34. 34. Features::Error Handling – Prod • Application level config of different kinds of errors 1 private void initExceptionHandeling() { 2 IApplicationSettings appSettings = getApplicationSettings(); 3 appSettings.setPageExpiredErrorPage(PageExpiredErrorPage.class); 4 appSettings.setAccessDeniedPage(AccessDeniedPage.class); 5 appSettings.setInternalErrorPage(InternalErrorPage.class); 6 getExceptionSettings().setUnexpectedExceptionDisplay(SHOW_INTERNAL_ERROR_PAGE); 7 } • Per page configuration 1 @Override 2 protected void onSubmit(AjaxRequestTarget target, Form form) { 3 Contact exampleContact = (Contact) SearchForm.this.getModelObject(); 4 try { 5 List<Contact> contacts = companyService.findContactsByExample(exampleContact); 6 contactsDataProvider.setData(contacts); 7 ResultsPanel resultsPanel = ((SearchPage) getPage()).getResultsPanel(); 8 target.addComponent(resultsPanel); 9 } catch (RuntimeException e) { 10 getRequestCycle().onRuntimeException(new SearchErrorPage(e), e); 11 } 12 } 35 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  35. 35. Features::Error Handling – Prod • onRuntimeException override in RequestCycle • In this case you get the actual exception object 1 @Override 2 public RequestCycle newRequestCycle(Request request, Response response) { 3 return new WebRequestCycle(this, (WebRequest) request, response) { 4 5 @Override 6 public Page onRuntimeException(Page page, RuntimeException e) { 7 return new InternalErrorPage(e); 8 } 9 }; 10 } 36 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  36. 36. Features::I18N Support • Full I18N of all the application using Resource bundles • Use <wicket:message key=“…quot;/> instead of hard-coded text 1 page.title= 1 page.title=Login 2 username= 2 username=<u>U</u>sername 3 password= 3 password=<u>P</u>assword 4 submit= 4 submit=Login 1 <tr> 2 <td valign=middle align=right width=25%><b><wicket:message key=quot;usernamequot;/></b></td> 3 <td valign=middle> 4 <input class=quot;loginFieldquot; type=quot;textquot; id=quot;usernamequot; size=quot;25quot; tabindex=1 5 accessKey=quot;uquot; wicket:id=quot;usernamequot;> 6 </td> 7 </tr> 37 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  37. 37. Features::L10N Support • Use “HTML Bundles” • Similar to resource bundles, but for HTML pages • LoginPage.html – default • LoginPage_iw.html – right-to-left 1 public WicketSession(Request request) { 2 super(request); 3 setLocale(new Locale(quot;iwquot;)); 4 } 1 <table class=quot;loginTablequot; border=quot;1quot; style=quot;direction: rtl;quot;> 2 <tr> 3 … 4 </tr> 5 </table> 38 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  38. 38. Features:: Documentation • Source • API documentation • Nabble • Forum & Mailing List • Books • Pro Wicket • Wicket in Action • Early Access available, in print next month • Sites (see References) 39 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  39. 39. Summary 40 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  40. 40. Summary Feature Summary Configuration No XML!  View technology Valid XHTML  Cut to pieces  Page flow No XML!  Form binding Swing-like models  Table sorting Eeeeasy  Pagination Eeeeasy  Validations No JS generation  AJAX Eeeeasy, but JS can be better  Error handling Powerful and configurable  I18n support Java resource bundles  Documentation Tons, can be organized better  41 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  41. 41. Summary::Java! • Fast learning curve • MVC at component level • Truly object oriented • Code centric • Trivial component creation • Java FWs integration • Full debuggability 42 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  42. 42. Summary::Cons • Internals are complex • The API is too big • No structured “Best Practices” • Documentation is a mess • Java limitations • Anonymous classes instead of closures • Generics troubles 43 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  43. 43. Summary::Cons • A lot of Java code required • Maintainability • No generics support in API (until 1.4) • No automatic client-side validation generation • Not suitable for very dynamic pages • HTML cut between different files • Not so comfortable for HTML coders 44 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  44. 44. Summary::The Future • Wicket 1.4 • Generics • Model<T> • Component<T> • M2 is available • Wicket 1.5 • Multiple extend/child areas • Proxy Model • Strongly typed properties • Tabbed browsers support • Many more 45 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  45. 45. Summary:: References • wicket.apache.org • cwiki.apache.org/WICKET • wicketstuff.org • www.wicket-library.com • issues.apache.org/jira/browse/WICKET 46 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
  46. 46. Thank You! 47 Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

×