wicket presentation @ alphacsp java web frameworks playoff 2008

Post on 19-May-2015

4.653 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

2

Apache Wicket – keep it simple!

Baruch Sadogursky

Consultant & Architect, AlphaCSP

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Agenda

• Introduction

• Framework features

• Summary

3

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

4

Introduction

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

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

1 <html>

2 <body>

3 <h1 wicket:id="message">Hello, World!</h1>

4 </body>

5 </html>

1 <html>

2 <body>

3 <h1 wicket:id="message">Hello, World!</h1>

4 </body>

5 </html>

1 public class HelloWorld extends WebPage {

2 public HelloWorld() {

3 add(new Label("message", "Hello, World!"));

4 }

5 }

Intro::Hello, World!

7

+

=

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Intro::Looks Familiar?

Wicket:

Swing:

8

1 public class HelloWorld extends JFrame {

2 public HelloWorld() {

3 add(new Label("Hello, World!"));

4 }

5 }

1 public class HelloWorld extends WebPage {

2 public HelloWorld() {

3 add(new Label("message", "Hello, World!"));

4 }

5 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Intro::History

9

Mar-04 Jun-08

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

Jonathan Locke envisioned and originated Wicket

May-05

JavaOne presentation

Jun-05

Wicket 1.0 final

Mar-06

Wicket 1.2 released

Jul-07

Apache Wicket

Jan-08

Wicket 1.3 released

Jun-08

Wicket 1.4 m2

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Intro::Wicket Hype

10

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

awt.Component

awt.Container

JContainer

JComponent

JPanel JLabel JButton

awt.Window

awt.Frame

JFrame

Intro:: Concepts – Components

12

Swing Wicket

Component

Label

WebComponent MarkupContainer

Page WebMarkupContainer

WebPage Panel Link

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

1 private IColumn[] getTableColumns() {

2 List<IColumn> columns = new ArrayList<IColumn>();

3 columns.add(new PropertyColumn(new ResourceModel("name"), "name", "name"));

4 columns.add(new PropertyColumn(new ResourceModel("department.name"), "department.name"));

5 columns.add(new TextFieldColumn(new ResourceModel("email"), "email"));

6 return columns.toArray(new IColumn[columns.size()]);

7 }

1 public LoginForm(MarkupContainer parent) {

2 super("loginForm", new CompoundPropertyModel(new User()));

3 parent.add(this);

4 add(new TextField("username").setRequired(true));

5 PasswordTextField passwordTextField = new PasswordTextField("password");

6 passwordTextField.setRequired(true);

7 add(passwordTextField);

8 …

9 }

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

13

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

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

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

1 protected void init() {

2 super.init();

3 addComponentInstantiationListener(new SpringComponentInjector(this));

4 getResourceSettings().setThrowExceptionOnMissingResource(true);

5 mountBookmarkablePage("hello_world.html", HelloWorld.class);

6 }

7

8 @Override

9 public Class getHomePage() {

10 return SearchPage.class;

11 }

Features::Configuration

• No Wicket XML files• Convention over configuration• Configuration done in Java• Spring integration

• Just enable injecting interceptor

17

1 @SpringBean

2 private UserService userService;

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

Features::View Technology

• Reuse HTML as it was Java• <wicket:child/>

• <wicket:extend/>

• <wicket:panel/>

19

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

3 <?xml version="1.0" encoding="UTF-8"?>

4 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/">

5 <head>

6 …

11 </head>

12 <body>

13 <wicket:child/>

14 </body>

15 </html>

1 <wicket:extend>

2 <div align="right" class="header" wicket:id="welcomePanel"></div>

3 <div class="phoneBook" align="center" wicket:id="searchPanel"></div>

4 <div class="phoneBook" align="center" wicket:id="resultsPanel"></div>

5 </wicket:extend>

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

1 <wicket:panel>

2 <table>

3 <tr>

4 <td class="header"><wicket:message key="user"/>: <span wicket:id="username"></span></td>

5 <td class="headerSeperator">|</td>

6 <td class="header"><a href="#" wicket:id="logout"><wicket:message key="logout"/></a></td>

7 </tr>

8 </table>

9 </wicket:panel>

Features::View Technology

• Reuse HTML as it was Java• <wicket:child/>

• <wicket:extend/>

• <wicket:panel/>

20

1 <wicket:extend>

2 <div align="right" class="header" wicket:id="welcomePanel"></div>

3 <div class="phoneBook" align="center" wicket:id="searchPanel"></div>

4 <div class="phoneBook" align="center" wicket:id="resultsPanel"></div>

5 </wicket:extend>

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Page Flow

• Inside onSubmit (buttons, links and forms)• setResponsePage(SomePage.class);

• setResponsePage(somePage);

21

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("Sorry, …");

11 setModelObject(new User());

12 }

13 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Form Binding

• Form is a component

• So, it is backed up with model

22

1 private SearchForm(MarkupContainer parent) {

2 super("searchForm", new CompoundPropertyModel(new Contact()));

3 parent.add(this);

4 add(new TextField("name"));

5 TextField emailTextField = new TextField("email");

6 emailTextField.add(EmailAddressValidator.getInstance());

7 add(emailTextField);

8 …

9 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Table Sorting

• Headers should be added to table

• Property expression is optionally passed when constructing Column

• If passed – the header will be clickable

23

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("name"), "name", "name"));

4 columns.add(new PropertyColumn(new ResourceModel("department.name"), "department.name"));

5 columns.add(new TextFieldColumn(new ResourceModel("email"), "email"));

6 return columns.toArray(new IColumn[columns.size()]);

7 }

8

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Table Sorting

• You generate the displayed data

• So, you are in charge of actual sorting

• Property expression and sort direction is provided

24

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 && "name".equals(sort.getProperty())) {

7 Collections.sort(sublist);

8 if (!sort.isAscending()) {

9 Collections.reverse(sublist);

10 }

11 }

12 return sublist.iterator();

13 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Pagination

• Navigation toolbar should be added to table (top or bottom)

• Rows per page count is passed in the constructor

25

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("resultsPanel");

3 DataTable contactsTable = new SortablePagedDataTable("contactsTable",

4 getTableColumns(), contactsDataProvider, 10);

5 add(contactsTable);

6 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Pagination

• You generate the displayed data

• So, you are in charge of actual sublisting

• First and count are provided

26

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 && "name".equals(sort.getProperty())) {

7 Collections.sort(sublist);

8 if (!sort.isAscending()) {

9 Collections.reverse(sublist);

10 }

11 }

12 return sublist.iterator();

13 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

• “Required” validation – just say

• Validation errors added to their own <div> (css it at will)

27

Features::Validations (Server)

1 public LoginForm(MarkupContainer parent) {

2 super("loginForm", new CompoundPropertyModel(new User()));

3 parent.add(this);

4 add(new TextField("username").setRequired(true));

5 PasswordTextField passwordTextField = new PasswordTextField("password");

6 passwordTextField.setRequired(true);

7 add(passwordTextField);

8 FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");

9 feedbackPanel.setEscapeModelStrings(false);

10 add(feedbackPanel);

11 }

1 <tr>

2 <td colspan="2" class="feedback" wicket:id="feedback"/>

3 </tr>

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

• Other validations – add Validators to the components

• 24 ready validators in wicket-core and wicket-extensions

28

Features::Validations (Server)

1 private SearchForm(MarkupContainer parent) {

2 super("searchForm", new CompoundPropertyModel(new Contact()));

3 parent.add(this);

4 add(new TextField("name"));

5 TextField emailTextField = new TextField("email");

6 emailTextField.add(EmailAddressValidator.getInstance());

7 …

12 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

Features::Validations (Client)

• Solution – call server-side validations in AJAX

• Same experience for the user

• Slower on slow connections

30

1 private SearchForm(MarkupContainer parent) {

2 super("searchForm", new CompoundPropertyModel(new Contact()));

3 parent.add(this);

4 add(new TextField("name"));

5 TextField emailTextField = new TextField("email");

6 emailTextField.add(EmailAddressValidator.getInstance());

7 …

8 AjaxFormValidatingBehavior.addToAllFormComponents(this, "onblur");

9 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::AJAX

• Use AJAX components instead of non-AJAX ones

• Add components to be refreshed

31

1 private SearchForm(MarkupContainer parent) {

2 super("searchForm", new CompoundPropertyModel(new Contact()));

3 parent.add(this);

4 …

12 add(new AjaxButton("submit", 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, "onblur");

24 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::AJAX

32

• JS is generated using Dojo and Script.aculo.us

• Automatic fallback to non-jscomponents

1 <script type="text/javascript"

2 src="resources/org.apache.wicket.markup.html.WicketEventReference/wicket-event.js">

3 </script>

4 <script type="text/javascript"

5 src="resources/org.apache.wicket.ajax.WicketAjaxReference/wicket-ajax.js">

6 </script>

7 <script type="text/javascript"

8 src="resources/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/wicket-ajax-debug.js">

9 </script>

10 <script type="text/javascript"

11 id="wicket-ajax-debug-enable"><!--/*--><![CDATA[/*><!--*/

12 wicketAjaxDebugEnable = true;

13 /*-->]]>*/</script>

14 <script type="text/javascript"

15 src="resources/org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteBehavior/wicket-autocomplete.js">

16 </script>

17 <script type="text/javascript"><!--/*--><![CDATA[/*><!--*/

18 Wicket.Event.add(window, "domready", function() {

19 new Wicket.AutoComplete('department2',

20 '?wicket:interface=:2:searchPanel:searchForm:department::IActivePageBehaviorListener:1:&wicket:ignoreIfNotActive=true',

21 false);

22 });

23 /*-->]]>*/</script>

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::AJAX

33

• Great debug utility

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Error Handling – Dev

• Very self-explanatory error pages

34

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Error Handling – Prod

35

• 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 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::Error Handling – Prod

• onRuntimeException override in RequestCycle

• In this case you get the actual exception object

36

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 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::I18N Support

• Full I18N of all the application using Resource bundles• Use <wicket:message key=“…"/>

instead of hard-coded text

37

1 <tr>

2 <td valign=middle align=right width=25%><b><wicket:message key="username"/></b></td>

3 <td valign=middle>

4 <input class="loginField" type="text" id="username" size="25" tabindex=1

5 accessKey="u" wicket:id="username">

6 </td>

7 </tr>

1 page.title=Login

2 username=<u>U</u>sername

3 password=<u>P</u>assword

4 submit=Login

1 page.title=

2 username=

3 password=

4 submit=

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

Features::L10N Support

• Use “HTML Bundles”• Similar to resource bundles, but for HTML pages

• LoginPage.html – default• LoginPage_iw.html – right-to-left

38

1 <table class="loginTable" border="1" style="direction: rtl;">

2 <tr>

3 …

4 </tr>

5 </table>

1 public WicketSession(Request request) {

2 super(request);

3 setLocale(new Locale("iw"));

4 }

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

Copyright AlphaCSP Israel 2008 – Web Framework Playoff Seminar

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

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

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

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

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

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

47

Thank

You!

top related