TeamStation AI System Report LATAM IT Salaries 2024
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
1.
2. Apache Wicket – keep it
simple!
Baruch Sadogursky
Consultant & Architect,
AlphaCSP
2
Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
3. Agenda
• Introduction
• Framework features
• Summary
3
Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
4. Introduction
4
Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
5. 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
6. 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
13. 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
14. 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
15. 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
16. Wicket Features Review
16
Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
17. 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
18. 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
19. 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
22. 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
23. 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
24. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
36. 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
37. 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
38. 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
39. 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
40. Summary
40
Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar
41. 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
42. 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
43. 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
44. 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
45. 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