SlideShare ist ein Scribd-Unternehmen logo
1 von 150
Introducing
Apache Wicket
Martijn Dashorst
Agenda


•   Introduction to Apache Wicket
•   New and noteworthy in 1.5
•   Questions
Martijn Dashorst

•   Employee @ Topicus
•   Chair for Apache Wicket
•   Committer
•   Apache Member
•   Author Wicket in Action
Introduction
Wicket is...
a component oriented web framework
using just HTML and Java
Apache Wicket

•   Open Source: ASL 2.0
•   Created in 2004
•   Java web framework
•   Component oriented
•   http://wicket.apache.org
Who’s using Wicket?
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
Wicket 2010
mobile.walmart.com supports three categories
of devices using the same Java code (only the html
is (very) different.)

Try doing that with JSP.
           — Joachim Kainz
... We at Vegas.com have been able to re-
purpose our Wicket-based air/hotel search
application and purchase/checkout application.
This is the new mexico.com. [...]

The re-use of components and abstract pages
was tremendous.

      —Scott Swank, chief architect vegas.com
Just HTML
Sign up form




Example from Railscast episode #250
Sign up form
Sign up form
  <h1>Sign Up</h1>

  <form>
   <div class="error_messages">
    <h2>Form is invalid</h2>
    <ul>
     <li>Some error message</li>
    </ul>
   </div>
   <p>
    <label for="email">E-Mail</label><br/>
    <input type="email" id="email" />
   </p>
   <p>
    <label for="password">Password</label>
    <input type="password" id="password" />
   </p>
   <p>
    <label for="confirm">Password confirmat
    <input type="password" id="confirm" />
   </p>
   <p class="button"><input type="submit" va
Sign up form
Sign up form
  <h1>Sign Up</h1>  
    
  <%= form_for @user do |f| %>  
    <% if @user.errors.any? %>  
      <div class="error_messages">  
        <h2>Form is invalid</h2>  
        <ul>  
          <% for message in @user.errors.full  
            <li><%= message %></li>  
          <% end %>  
        </ul>  
      </div>  
    <% end %>  
    <p>  
      <%= f.label :email %><br />  
      <%= f.text_field :email %>  
    </p>  
    <p>  
      <%= f.label :password %><br />  
      <%= f.password_field :password %>  
    </p>  
    <p>
Sign up form
  <h1>Sign Up</h1>

  <form>
   <div class="error_messages">
    <h2>Form is invalid</h2>
    <ul>
     <li>Some error message</li>
    </ul>
   </div>
   <p>
    <label for="email">E-Mail</label><br/>
    <input type="email" id="email" />
   </p>
   <p>
    <label for="password">Password</label>
    <input type="password" id="password" />
   </p>
   <p>
    <label for="confirm">Password confirmat
    <input type="password" id="confirm" />
   </p>
   <p class="button"><input type="submit" va
Sign up form
  <h1>Sign Up</h1>

  <form>
   <div wicket:id="feedback" class="error_me
    <h2>Form is invalid</h2>
    <ul>
     <li>Some error message</li>
    </ul>
   </div>
   <p>
    <label for="email">E-Mail</label><br/>
    <input wicket:id="email" type="email" i
   </p>
   <p>
    <label for="password">Password</label>
    <input wicket:id="password" type="passw
   </p>
   <p>
    <label for="confirm">Password confirmat
    <input wicket:id="confirm" type="passwo
   </p>
   <p class="button"><input type="submit" va
Sign up form
  <h1>Sign Up</h1>

  <form>
   <div wicket:id="feedback" class="error_me
    <h2>Form is invalid</h2>
    <ul>
     <li>Some error message</li>
    </ul>
   </div>
   <p>
    <label for="email">E-Mail</label><br/>
    <input wicket:id="email" type="email" i
   </p>
   <p>
    <label for="password">Password</label>
    <input wicket:id="password" type="passw
   </p>
   <p>
    <label for="confirm">Password confirmat
    <input wicket:id="confirm" type="passwo
   </p>
   <p class="button"><input type="submit" va
<tag wicket:id="foo">
Instructs Wicket to work on this tag
Imperative markup
                               <h1>Sign Up</h1>

•   Used by Ruby on Rails,     <%= form_for @user do |f| %>
                                 <% if @user.errors.any? %>
    JSP, Play, Velocity, ...       <div class="error_messag
                                     <h2>Form is invalid</h

•
                                     <ul>
    Great for web developers           <% for message in @u
                                         <li><%= message %>
•   Great for hacking on a             <% end %>
                                     </ul>
    web site                       </div>
                                 <% end %>
                                 <p>
•   Code and markup are            <%= f.label :email %><br
                                   <%= f.text_field :email 
    not separated                </p>
                                 <p>
Declarative markup
                                <h1>Sign Up</h1>

•   Used by Wicket, Tapestry,   <form wicket:id="form">
                                 <div class="error_message
    Facelets                     <p>
                                  <label for="email">E-Ma

•   Great for web designers
                                  <input type="email" id=
                                 </p>
                                 <p>
•   Go from PSD → HTML →          <label for="password">P
                                  <input type="password"
    Page → Component             </p>
                                 <p>
                                  <label for="confirm">Pa
•   Code and markup are           <input type="password"
                                 </p>
    strictly separated           <p class="button"><input
                                </form>
Just Java
Sign up form
<h1>Sign Up</h1>  
  
<%= form_for @user do |f| %>  
  <% if @user.errors.any? %>  
    <div class="error_messages">  
      <h2>Form is invalid</h2>  
      <ul>  
        <% for message in @user.errors.full_messages %>  
          <li><%= message %></li>  
        <% end %>  
      </ul>  
    </div>  
  <% end %>  
  <p>  
    <%= f.label :email %><br />  
    <%= f.text_field :email %>  
  </p>  
  <p>  
    <%= f.label :password %><br />  
    <%= f.password_field :password %>  
  </p>  
  <p>  
    <%= f.label :password_confirmation %>  
Sign up form
Form form = new Form("signup") {
  @Override
  public void onSubmit() {
     // ...
  }
}
add(form);
Sign up form
Form form = new Form("signup") {
  @Override
  public void onSubmit() {
     // ...
  }
}
add(form);

FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setVisible(form.hasFeedbackMessages());
form.add(feedback);
Sign up form
Form form = new Form("signup") {
  @Override
  public void onSubmit() {
     // ...
  }
}
add(form);

FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setVisible(form.hasFeedbackMessages());
form.add(feedback);

form.add(new EmailTextField("email", Model.of(""))
         .setRequired(true));
Sign up form
Form form = new Form("signup") {
  @Override
  public void onSubmit() {
     // ...
  }
}
add(form);

FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setVisible(form.hasFeedbackMessages());
form.add(feedback);

form.add(new EmailTextField("email", Model.of(""))
         .setRequired(true));

form.add(new PasswordField("password", Model.of(""))
         .setRequired(true));
Sign up form
Form form = new Form("signup") {
  @Override
  public void onSubmit() {
     // ...
  }
}
add(form);

FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setVisible(form.hasFeedbackMessages());
form.add(feedback);

form.add(new EmailTextField("email", Model.of(""))
         .setRequired(true));

form.add(new PasswordField("password", Model.of(""))
         .setRequired(true));

form.add(new PasswordField("confirm", Model.of(""))
         .setRequired(true));
Just Java

•   No logic in markup
•   Components are objects (use new and extends)
•   Use OO techniques in your programming
•   No XML
Concepts
Components
•   Manipulate markup
•   Render content
•   Receive events (onClick, onSubmit)


•   Examples:
    Label, Link, Form, TextField, PagingNavigator, Panel,
    Page, ClientSideImageMap
Models

•   Provide data to components
•   Store data for components
•   Transform data
•   Retrieve data from persistent storage


•   Examples: Model<T>, PropertyModel<T>
Behaviors

•   Decorator/Adapter for Component
•   Can manipulate markup of Component
•   Can receive events (onClick)
•   Add Ajax functionality to components
•   Example: AjaxSelfUpdatingTimerBehavior
Getting started
Wicket projects
•   Apache Wicket                                •   Leg before Wicket
    (extensions, spring, guice, velocity, etc)       (Maven archetypes)


•   Wicket stuff                                 •   Apache Isis
    (grand collection of projects)                   (incubating, DDD framework)


•   Seam for Apache                              •   Jolira Tools
    Wicket                                           (powers mobile.walmart.com)


•   WiQuery                                      •   Visural Wicket
                                                     (standalone Wicket components)
    (JQuery integration library)
Apache Wicket projects
•   Core          •   Velocity
•   Extensions    •   Auth/Roles
•   Quick start   •   JMX
•   IoC           •   Dev utils
    •   Spring
    •   Guice     •   Examples

•   DateTime
Wicket Stuff projects
•   progressbar              •   shiro-security                 •   theme

•   datatable-autocomplete   •   gae-initializer                •   yav

•   flot                      •   push-jdk-1.5                   •   maven-support

•   googlecharts             •   jasperreports                  •   plugin

•   scala-extensions         •   mbeanview                      •   input-events

•   openlayers               •   jsr303                         •   javaee-inject

•   gmap2                    •   client-and-server-validation   •   push

•   inmethod-grid            •   multi-text-input               •   wicket-html5

•   minis                    •   prototype                      •   wicket-servlet3

•   phonebook                •   simile-timeline
Quick start
Quick start
Running quickstart
$_
Running quickstart
$ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket -
DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5-
SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject -
DarchetypeRepository=https://repository.apache.org/content/repositories/
snapshots/ -DinteractiveMode=false _
Running quickstart
$ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket -
DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5-
SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject -
DarchetypeRepository=https://repository.apache.org/content/repositories/
snapshots/ -DinteractiveMode=false
[INFO] Scanning for projects...
[INFO] -----------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] -----------------------------------------------------------
[INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) >>>
[INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) <<<
[INFO] --- maven-archetype-plugin:2.0:generate (default-cli) ---
[INFO] Generating project in Batch mode
[INFO] Archetype defined by properties
[INFO] -----------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------
[INFO] Total time: 1.279s
[INFO] Finished at: Fri Feb 04 22:04:14 CET 2011
[INFO] Final Memory: 9M/81M
[INFO] -----------------------------------------------------------
Running quickstart
$ mvn jetty:run_
Running quickstart
$ mvn jetty:run
[INFO] Scanning for projects...
[INFO] -----------------------------------------------------------
[INFO] Building quickstart 1.0-SNAPSHOT
[INFO] -----------------------------------------------------------
[INFO] Starting jetty 7.2.2.v20101205 ...
2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205
2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo
INFO - WebXmlFile               - web.xml: found filter with na
INFO - Application             - [wicket.myproject] init: Wick
INFO - RequestListenerInterface - registered listener interface
INFO - WebApplication             - [wicket.myproject] Started Wi
******************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode.               ***
***                      ^^^^^^^^^^^               ***
*** Do NOT deploy to your live server(s) without changing this.***
*** See Application#getConfigurationType() for more information***
******************************************************************
2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
Running quickstart
Quick start alternative
           Leg up
           •   Spring
           •   Guice
           •   JDBC
           •   JPA
           •   Hibernate
           •   Scala

           http://jweekend.com/dev/LegUp
Want to learn more?
Want to learn more?
Want to learn more?

http://wicket.apache.org/learn/books.html
Examples
Examples
Hello, World!
Hello, World!
<h1>Hello, World</h1>
Hello, World!
<h1>[Replaced text]</h1>
Hello, World!
<h1 wicket:id="msg">[Replaced text]</h1>
Hello, World!
<h1 wicket:id="msg">[Replaced text]</h1>

                   +

 add(new Label("msg", "Hello, World!"));
Hello, World!
<h1 wicket:id="msg">[Replaced text]</h1>

                    +

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

                    =

        <h1>Hello, World!</h1>
Examples
Click counter
This link has been clicked 123 times
This link has been clicked 123 times

This link has been clicked 123 times!
This link has been clicked 123 times

This <a href="#">link</a> has been clicked 123
times!
This link has been clicked 123 times

This <a href="#">link</a> has been clicked
<span>123</span> times!
This link has been clicked 123 times

This <a wicket:id="link" href="#">link</a> has been
clicked <span>123</span> times!
This link has been clicked 123 times

This <a wicket:id="link" href="#">link</a> has been
clicked
<span wicket:id="clicks">123</span> times!
This link has been clicked 123 times

This <a wicket:id="link" href="#">link</a> has been
clicked
<span wicket:id="clicks">123</span> times!
This link has been clicked 123 times

public class ClickCountPage extends WebPage {
}
This link has been clicked 123 times

public class ClickCountPage extends WebPage {
  public ClickCountPage() {
  }
}
This link has been clicked 123 times

public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCountPage() {
    }
}
This link has been clicked 123 times

public class ClickCountPage extends WebPage {
 private int clicks = 0;

 public ClickCountPage() {
   add(new Link<Void>("link") {
      public void onClick() {
        clicks++;
      }
    });
 }
This link has been clicked 123 times

public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCountPage() {
      add(new Link<Void>("link") { ... });
      add(new Label("clicks",
          new PropertyModel<Integer>(this,
                "clicks")));
    }
}
Wicket for developers
2 modes for your app
Development and Deployment
Development mode
$ mvn jetty:run
[INFO] Scanning for projects...
[INFO] -----------------------------------------------------------
[INFO] Building quickstart 1.0-SNAPSHOT
[INFO] -----------------------------------------------------------
[INFO] Starting jetty 7.2.2.v20101205 ...
2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205
2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo
INFO - WebXmlFile               - web.xml: found filter with na
INFO - Application             - [wicket.myproject] init: Wick
INFO - RequestListenerInterface - registered listener interface
INFO - WebApplication             - [wicket.myproject] Started Wi
******************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode.               **
***                      ^^^^^^^^^^^               **
*** Do NOT deploy to your live server(s) without changing this. **
*** See Application#getConfigurationType() for more information **
******************************************************************
2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
Development mode
•   exceptional error pages
•   dynamic markup reloading
•   no caching
•   no javascript/css optimizations
•   discover mistakes early (serialization, missing
    components, ...)
•   Wicket debugger visible
Deployment mode

•   Cache markup resources
•   No checks
•   Don’t display stack traces to users
•   Minimize/compress JavaScript
•   Don’t generate wicket tags
•   Wicket debugger not visible
FREE PRO TIP:

Don’t perform your performance tests
in development mode!
Ajax debugger
Ajax debugger
Ajax envelope
<?xml version="1.0" encoding="UTF-8"?>
<ajax-response>
 <component id="count2">
  <![CDATA[<span wicket:id="count" id="count2">1</span>]]>
 </component>
</ajax-response>
Error message
Unable to find component with id 'count'
in HomePage.
This means that you declared
wicket:id=count in your markup, but that
you either did not add the component to
your page at all, or that the hierarchy does
not match.
Error pages
Testing the UI
WicketTester

•   Test components directly, or their markup
•   Runs tests without starting server
•   Ajax testing (server side)
•   Runs in IDE, ant, maven builds
•   Achieves high code coverage
Testing Hello, World!
@Test
public void rendersWelcomeMessage() {
}
Testing Hello, World!
@Test
public void rendersWelcomeMessage() {
  WicketTester tester = new WicketTester();
}
Testing Hello, World!
@Test
public void rendersWelcomeMessage() {
  WicketTester tester = new WicketTester();
  tester.startPage(HelloWorldPage.class);
}
Testing Hello, World!
@Test
public void rendersWelcomeMessage() {
  WicketTester tester = new WicketTester();
  tester.startPage(HelloWorldPage.class);
  tester.assertLabel("msg", "Hello, World!");
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
  WicketTester tester = new WicketTester();
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
  WicketTester tester = new WicketTester();
  tester.startPage(ClickCountPage.class);
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
  WicketTester tester = new WicketTester();
  tester.startPage(ClickCountPage.class);
  tester.assertModelValue("clicks", 0);
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
  WicketTester tester = new WicketTester();
  tester.startPage(ClickCountPage.class);
  tester.assertModelValue("clicks", 0);
  tester.clickLink("link");
}
Testing Click Count
@Test
public void clicksIncreaseCount() {
  WicketTester tester = new WicketTester();
  tester.startPage(ClickCountPage.class);
  tester.assertModelValue("clicks", 0);
  tester.clickLink("link");
  tester.assertModelValue("clicks", 1);
}
Other test frameworks


•   PageTest (by Kent Tong)
•   JDave (BDD framework)
Summary

•   Widely used
•   Component oriented
•   Java
•   Open Source (ASL 2.0)
What’s new in 1.5?
HTML 5 support
Pre 1.5


•   Checks for valid markup don’t accept new field types
•   HTML 5 defines:
    <input type=”text|email|password|number|date|
    search|url|...”>
Wicket 1.5

•   EmailTextField
•   NumberTextField
•   UrlTextField
•   RangeTextField
Improved internals
Split up core library
•   Old:
    •   wicket.jar
Split up core library
•   Old:
    •   wicket.jar
•   New:
    •   wicket-requests.jar
    •   wicket-util.jar
    •   wicket-core.jar
Maven users
<dependency>
  <groupId>org.apache.wicket</groupId>
  <artifactId>wicket-core</artifactId>
  <version>1.5-RC1</version>
</dependency>
Simpler request cycle
Wicket < 1.5

•   Decoding request and handling in state machine
•   Debugging ‘interesting’
•   Designed for flexibility
•   Served its purpose—took on 4 years of engineering
Wicket 1.5


•   Request cycle processing completely rewritten
•   Rendering code has been improved and simplified
•   URL rendering simplified: now in one place
Wicket < 1.5

•   Custom request cycle: subclass WebRequestCycle
•   Problematic with add-ons:
    •   HibernateRequestCycle
    •   SecureRequestCycle
    •   ActivityRequestCycle
New: RequestCycleListener
public interface IRequestCycleListener {

    void onBeginRequest(RequestCycle cycle);

    void onEndRequest(RequestCycle cycle);

    void onDetach(RequestCycle cycle);

    IRequestHandler onException(RequestCycle cycle, Exception ex);
}
RequestCycleListener
public class SomeWebApplication extends WebApplication {
  @Override
  protected void init() {
  }

    @Override
    public Class<? extends Page> getHomePage() {
      return SomePage.class;
    }
}
RequestCycleListener
public class SomeWebApplication extends WebApplication {
  @Override
  protected void init() {
     addRequestCycleListener(new IRequestCycleListener() {
        public void onBeginRequest() {
           // do something at the beginning of the request
        }

              public void onEndRequest() {
                // do something at the end of the request
              }

              public void onException(Exception ex) {
                // do something here when there's an exception
              }
        });
    }

    @Override
    public Class<? extends Page> getHomePage() {
      return SomePage.class;
    }
}
Switching to HTTPS
Switching to HTTPS
public SecurePage extends WebPage {
  ...
}

public MyApplications extends WebApplication {
 @Override
 public void init() {
  super.init();

    }
}
Switching to HTTPS
@RequireHttps
public SecurePage extends WebPage {
  ...
}

public MyApplications extends WebApplication {
 @Override
 public void init() {
  super.init();

    }
}
Switching to HTTPS
@RequireHttps
public SecurePage extends WebPage {
  ...
}

public MyApplications extends WebApplication {
  @Override
  public void init() {
    super.init();
    setRootRequestMapper(
      new HttpsMapper(getRootRequestMapper(),
                  new HttpsConfig());
  }
}
Component event bus
Component event bus

•   IEventSource: objects that send events
    <T> void send(IEventSink sink,
                      Broadcast broadcast, T payload);
•   IEventSink: objects that receive events
    void onEvent(IEvent<?> event);
•   Participants: Components, RequestCycle, Session and
    Application
Event bus example
Ajax link counter
This link has been clicked 123 times
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new Link<Void>("link") {
          @Override
          public void onClick() {
            count++;
          }
        });
      add(new Label("clicks",
               new PropertyModel<Integer>(this, "clicks")));
    }
}
This link has been clicked 123 times
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new Link<Void>("link") {
          @Override
          public void onClick() {
            count++;
          }
        });
      add(new Label("clicks",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
This link has been clicked 123 times
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
          }
        });
      add(new Label("clicks",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
This link has been clicked 123 times
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
             target.add(getPage().get("count"));
          }
        });
      add(new Label("count",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
This link has been clicked 123 times
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
            target.add(getPage().get("count"));
          }
        });
      add(new Label("count",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
Pre-event bus

•   Link needs to know the updatable components
•   Makes code brittle, hard to maintain


•   Better:
    •   Let the label refresh itself with each Ajax request
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
             target.add(getPage().get("count"));
          }
        });
      add(new Label("count",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
             send(getPage(), Broadcast.BREADTH, target);
          }
        });
      add(new Label("count",
                new PropertyModel<Integer>(this, "clicks"))
            .setOutputMarkupId(true));
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") {
          @Override
          public void onClick(AjaxRequestTarget target) {
            count++;
            send(getPage(), Broadcast.BREADTH, target);
          }
        });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") { ... });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }

    public class CountLabel extends Label {
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") { ... });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }

    public class CountLabel extends Label {
      public CountLabel(String id, IModel<Integer> model) {
        super(id, model);
      }
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") { ... });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }

    public class CountLabel extends Label {
      public CountLabel(String id, IModel<Integer> model) {
        super(id, model);
        setOutputMarkupId(true);
      }
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") { ... });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }

    public class CountLabel extends Label {
     public CountLabel(String id, IModel<Integer> model) {
       super(id, model);
       setOutputMarkupId(true);
     }

        @Override
        public void onEvent(IEvent<?> event) {
          super.onEvent(event);
        }
    }
}
public class ClickCountPage extends WebPage {
 private int clicks = 0;

    public ClickCount() {
      add(new AjaxLink<Void>("link") { ... });
      add(new CountLabel("count", new PropertyModel<Integer>(this,
    }

    public class CountLabel extends Label {
     public CountLabel(String id, IModel<Integer> model) {
       super(id, model);
       setOutputMarkupId(true);
     }

        @Override
        public void onEvent(IEvent<?> event) {
         super.onEvent(event);

            if (event.getPayload() instanceof AjaxRequestTarget) {
              AjaxRequestTarget target =
                          (AjaxRequestTarget) event.getPayload();
              target.add(this);
            }
        }
    }
}
Post-event bus

•   A bit more code
•   Updates are now completely decoupled
•   Make the payload type safe and meaningful:
    no AjaxRequestTarget, but CountEvent
•   AJAX requests trigger a default event with an
    AjaxRequestTarget as payload
And much, much more:
http://cwiki.apache.org/WICKET/
migration-to-wicket15.html
Thank you!
    Questions? Ask!

Weitere ähnliche Inhalte

Was ist angesagt?

HTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsHTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsJames Pearce
 
Keypoints html5
Keypoints html5Keypoints html5
Keypoints html5dynamis
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web appsIvano Malavolta
 
Backbone JS for mobile apps
Backbone JS for mobile appsBackbone JS for mobile apps
Backbone JS for mobile appsIvano Malavolta
 
Usability in the GeoWeb
Usability in the GeoWebUsability in the GeoWeb
Usability in the GeoWebDave Bouwman
 
Basics of css and xhtml
Basics of css and xhtmlBasics of css and xhtml
Basics of css and xhtmlsagaroceanic11
 
Web Standards: Fueling Innovation [Web Design World Boston '08]
Web Standards: Fueling Innovation [Web Design World Boston '08]Web Standards: Fueling Innovation [Web Design World Boston '08]
Web Standards: Fueling Innovation [Web Design World Boston '08]Aaron Gustafson
 
Rails for Mobile Devices @ Conferencia Rails 2011
Rails for Mobile Devices @ Conferencia Rails 2011Rails for Mobile Devices @ Conferencia Rails 2011
Rails for Mobile Devices @ Conferencia Rails 2011Alberto Perdomo
 
Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)Hendrik Ebbers
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법Jeado Ko
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1James Pearce
 
Introduction to HTML5
Introduction to HTML5Introduction to HTML5
Introduction to HTML5Gil Fink
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien Lecomte
 
Templates
TemplatesTemplates
Templatessoon
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptfranksvalli
 
Week 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuWeek 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuAppUniverz Org
 

Was ist angesagt? (20)

HTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applicationsHTML5 and the dawn of rich mobile web applications
HTML5 and the dawn of rich mobile web applications
 
Keypoints html5
Keypoints html5Keypoints html5
Keypoints html5
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web apps
 
DirectToWeb 2.0
DirectToWeb 2.0DirectToWeb 2.0
DirectToWeb 2.0
 
Backbone JS for mobile apps
Backbone JS for mobile appsBackbone JS for mobile apps
Backbone JS for mobile apps
 
Usability in the GeoWeb
Usability in the GeoWebUsability in the GeoWeb
Usability in the GeoWeb
 
Basics of css and xhtml
Basics of css and xhtmlBasics of css and xhtml
Basics of css and xhtml
 
Web Standards: Fueling Innovation [Web Design World Boston '08]
Web Standards: Fueling Innovation [Web Design World Boston '08]Web Standards: Fueling Innovation [Web Design World Boston '08]
Web Standards: Fueling Innovation [Web Design World Boston '08]
 
Rails for Mobile Devices @ Conferencia Rails 2011
Rails for Mobile Devices @ Conferencia Rails 2011Rails for Mobile Devices @ Conferencia Rails 2011
Rails for Mobile Devices @ Conferencia Rails 2011
 
Rails + Webpack
Rails + WebpackRails + Webpack
Rails + Webpack
 
Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)Web Components & Polymer 1.0 (Webinale Berlin)
Web Components & Polymer 1.0 (Webinale Berlin)
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
 
Why Django for Web Development
Why Django for Web DevelopmentWhy Django for Web Development
Why Django for Web Development
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1
 
Introduction to HTML5
Introduction to HTML5Introduction to HTML5
Introduction to HTML5
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
Templates
TemplatesTemplates
Templates
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScript
 
Week 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuWeek 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. Wu
 
jQuery UI and Plugins
jQuery UI and PluginsjQuery UI and Plugins
jQuery UI and Plugins
 

Andere mochten auch

Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 
Lombokのススメ
LombokのススメLombokのススメ
Lombokのススメなべ
 
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Baruch Sadogursky
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaMartijn Dashorst
 
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...Gerke Max Preussner
 
Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket IntroductionEyal Golan
 

Andere mochten auch (10)

Wicket体験談
Wicket体験談Wicket体験談
Wicket体験談
 
Project Lombok!
Project Lombok!Project Lombok!
Project Lombok!
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 
Lombok ハンズオン
Lombok ハンズオンLombok ハンズオン
Lombok ハンズオン
 
Lombokのススメ
LombokのススメLombokのススメ
Lombokのススメ
 
The State of Wicket
The State of WicketThe State of Wicket
The State of Wicket
 
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just Java
 
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
 
Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket Introduction
 

Ähnlich wie Wicket 2010

Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2RORLAB
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5Tieturi Oy
 
QuickConnect
QuickConnectQuickConnect
QuickConnectAnnu G
 
GitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scalatakezoe
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Arun Gupta
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigWake Liu
 
SPTechCon Dev Days - Third Party jQuery Libraries
SPTechCon Dev Days - Third Party jQuery LibrariesSPTechCon Dev Days - Third Party jQuery Libraries
SPTechCon Dev Days - Third Party jQuery LibrariesMark Rackley
 
Utilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterMark Rackley
 
django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030Kevin Wu
 
Web Components for Java Developers
Web Components for Java DevelopersWeb Components for Java Developers
Web Components for Java DevelopersJoonas Lehtinen
 
Polytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilarePolytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilareOluwadamilare Ibrahim
 
Polytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilarePolytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilareOluwadamilare Ibrahim
 
`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew Ivasiv`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew IvasivLemberg Solutions
 
SPTechCon DevDays - SharePoint & jQuery
SPTechCon DevDays - SharePoint & jQuerySPTechCon DevDays - SharePoint & jQuery
SPTechCon DevDays - SharePoint & jQueryMark Rackley
 
Introduction to web components
Introduction to web componentsIntroduction to web components
Introduction to web componentsMarc Bächinger
 
SPTechCon Boston 2015 - Utilizing jQuery in SharePoint
SPTechCon Boston 2015 - Utilizing jQuery in SharePointSPTechCon Boston 2015 - Utilizing jQuery in SharePoint
SPTechCon Boston 2015 - Utilizing jQuery in SharePointMark Rackley
 

Ähnlich wie Wicket 2010 (20)

Mobile themes, QR codes, and shortURLs
Mobile themes, QR codes, and shortURLsMobile themes, QR codes, and shortURLs
Mobile themes, QR codes, and shortURLs
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
 
QuickConnect
QuickConnectQuickConnect
QuickConnect
 
GitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scala
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # Twig
 
SPTechCon Dev Days - Third Party jQuery Libraries
SPTechCon Dev Days - Third Party jQuery LibrariesSPTechCon Dev Days - Third Party jQuery Libraries
SPTechCon Dev Days - Third Party jQuery Libraries
 
HTML5 Refresher
HTML5 RefresherHTML5 Refresher
HTML5 Refresher
 
Utilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done Faster
 
django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030
 
Semantic UI Introduction
Semantic UI IntroductionSemantic UI Introduction
Semantic UI Introduction
 
Web Components for Java Developers
Web Components for Java DevelopersWeb Components for Java Developers
Web Components for Java Developers
 
Polytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilarePolytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilare
 
Polytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilarePolytechnic speaker deck oluwadamilare
Polytechnic speaker deck oluwadamilare
 
`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew Ivasiv`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew Ivasiv
 
SPTechCon DevDays - SharePoint & jQuery
SPTechCon DevDays - SharePoint & jQuerySPTechCon DevDays - SharePoint & jQuery
SPTechCon DevDays - SharePoint & jQuery
 
Introduction to web components
Introduction to web componentsIntroduction to web components
Introduction to web components
 
SPTechCon Boston 2015 - Utilizing jQuery in SharePoint
SPTechCon Boston 2015 - Utilizing jQuery in SharePointSPTechCon Boston 2015 - Utilizing jQuery in SharePoint
SPTechCon Boston 2015 - Utilizing jQuery in SharePoint
 

Mehr von Martijn Dashorst

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0Martijn Dashorst
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsMartijn Dashorst
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLMartijn Dashorst
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails Martijn Dashorst
 
Whats up with wicket 8 and java 8
Whats up with wicket 8 and java 8Whats up with wicket 8 and java 8
Whats up with wicket 8 and java 8Martijn Dashorst
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep DiveMartijn Dashorst
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsMartijn Dashorst
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Martijn Dashorst
 
Wicket 10 years and beyond
Wicket   10 years and beyond Wicket   10 years and beyond
Wicket 10 years and beyond Martijn Dashorst
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeMartijn Dashorst
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschapMartijn Dashorst
 
Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in productionMartijn Dashorst
 
Wicket In Action - oredev2008
Wicket In Action - oredev2008Wicket In Action - oredev2008
Wicket In Action - oredev2008Martijn Dashorst
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheMartijn Dashorst
 

Mehr von Martijn Dashorst (20)

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud Deployments
 
SOLID principles
SOLID principlesSOLID principles
SOLID principles
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails
 
Whats up with wicket 8 and java 8
Whats up with wicket 8 and java 8Whats up with wicket 8 and java 8
Whats up with wicket 8 and java 8
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijs
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
 
De schone coder
De schone coderDe schone coder
De schone coder
 
Wicket 10 years and beyond
Wicket   10 years and beyond Wicket   10 years and beyond
Wicket 10 years and beyond
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschap
 
Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
 
Wicket In Action - oredev2008
Wicket In Action - oredev2008Wicket In Action - oredev2008
Wicket In Action - oredev2008
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at Apache
 
Wicket In Action
Wicket In ActionWicket In Action
Wicket In Action
 
Wicket Live on Stage
Wicket Live on StageWicket Live on Stage
Wicket Live on Stage
 

Kürzlich hochgeladen

OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Introduction to Quantum Computing
Introduction to Quantum ComputingIntroduction to Quantum Computing
Introduction to Quantum ComputingGDSC PJATK
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataCloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataSafe Software
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServiceRenan Moreira de Oliveira
 
Babel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxBabel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxYounusS2
 
GenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncGenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncObject Automation
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdfJamie (Taka) Wang
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
RAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIRAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIUdaiappa Ramachandran
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 

Kürzlich hochgeladen (20)

OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Introduction to Quantum Computing
Introduction to Quantum ComputingIntroduction to Quantum Computing
Introduction to Quantum Computing
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataCloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
 
Babel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxBabel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptx
 
GenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncGenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation Inc
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
RAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIRAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AI
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 

Wicket 2010

  • 2. Agenda • Introduction to Apache Wicket • New and noteworthy in 1.5 • Questions
  • 3. Martijn Dashorst • Employee @ Topicus • Chair for Apache Wicket • Committer • Apache Member • Author Wicket in Action
  • 5. Wicket is... a component oriented web framework using just HTML and Java
  • 6. Apache Wicket • Open Source: ASL 2.0 • Created in 2004 • Java web framework • Component oriented • http://wicket.apache.org
  • 25. mobile.walmart.com supports three categories of devices using the same Java code (only the html is (very) different.) Try doing that with JSP. — Joachim Kainz
  • 26. ... We at Vegas.com have been able to re- purpose our Wicket-based air/hotel search application and purchase/checkout application. This is the new mexico.com. [...] The re-use of components and abstract pages was tremendous. —Scott Swank, chief architect vegas.com
  • 28. Sign up form Example from Railscast episode #250
  • 30. Sign up form <h1>Sign Up</h1> <form> <div class="error_messages"> <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input type="email" id="email" /> </p> <p> <label for="password">Password</label> <input type="password" id="password" /> </p> <p> <label for="confirm">Password confirmat <input type="password" id="confirm" /> </p> <p class="button"><input type="submit" va
  • 32. Sign up form <h1>Sign Up</h1>      <%= form_for @user do |f| %>     <% if @user.errors.any? %>       <div class="error_messages">         <h2>Form is invalid</h2>         <ul>           <% for message in @user.errors.full             <li><%= message %></li>           <% end %>         </ul>       </div>     <% end %>     <p>       <%= f.label :email %><br />       <%= f.text_field :email %>     </p>     <p>       <%= f.label :password %><br />       <%= f.password_field :password %>     </p>     <p>
  • 33. Sign up form <h1>Sign Up</h1> <form> <div class="error_messages"> <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input type="email" id="email" /> </p> <p> <label for="password">Password</label> <input type="password" id="password" /> </p> <p> <label for="confirm">Password confirmat <input type="password" id="confirm" /> </p> <p class="button"><input type="submit" va
  • 34. Sign up form <h1>Sign Up</h1> <form> <div wicket:id="feedback" class="error_me <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input wicket:id="email" type="email" i </p> <p> <label for="password">Password</label> <input wicket:id="password" type="passw </p> <p> <label for="confirm">Password confirmat <input wicket:id="confirm" type="passwo </p> <p class="button"><input type="submit" va
  • 35. Sign up form <h1>Sign Up</h1> <form> <div wicket:id="feedback" class="error_me <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input wicket:id="email" type="email" i </p> <p> <label for="password">Password</label> <input wicket:id="password" type="passw </p> <p> <label for="confirm">Password confirmat <input wicket:id="confirm" type="passwo </p> <p class="button"><input type="submit" va
  • 37. Imperative markup <h1>Sign Up</h1> • Used by Ruby on Rails, <%= form_for @user do |f| %>   <% if @user.errors.any? %> JSP, Play, Velocity, ...     <div class="error_messag       <h2>Form is invalid</h •       <ul> Great for web developers         <% for message in @u           <li><%= message %> • Great for hacking on a         <% end %>       </ul> web site     </div>   <% end %>   <p> • Code and markup are     <%= f.label :email %><br     <%= f.text_field :email  not separated   </p>   <p>
  • 38. Declarative markup <h1>Sign Up</h1> • Used by Wicket, Tapestry, <form wicket:id="form"> <div class="error_message Facelets <p> <label for="email">E-Ma • Great for web designers <input type="email" id= </p> <p> • Go from PSD → HTML → <label for="password">P <input type="password" Page → Component </p> <p> <label for="confirm">Pa • Code and markup are <input type="password" </p> strictly separated <p class="button"><input </form>
  • 41. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form);
  • 42. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback);
  • 43. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true));
  • 44. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true)); form.add(new PasswordField("password", Model.of("")) .setRequired(true));
  • 45. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true)); form.add(new PasswordField("password", Model.of("")) .setRequired(true)); form.add(new PasswordField("confirm", Model.of("")) .setRequired(true));
  • 46. Just Java • No logic in markup • Components are objects (use new and extends) • Use OO techniques in your programming • No XML
  • 48. Components • Manipulate markup • Render content • Receive events (onClick, onSubmit) • Examples: Label, Link, Form, TextField, PagingNavigator, Panel, Page, ClientSideImageMap
  • 49. Models • Provide data to components • Store data for components • Transform data • Retrieve data from persistent storage • Examples: Model<T>, PropertyModel<T>
  • 50. Behaviors • Decorator/Adapter for Component • Can manipulate markup of Component • Can receive events (onClick) • Add Ajax functionality to components • Example: AjaxSelfUpdatingTimerBehavior
  • 52. Wicket projects • Apache Wicket • Leg before Wicket (extensions, spring, guice, velocity, etc) (Maven archetypes) • Wicket stuff • Apache Isis (grand collection of projects) (incubating, DDD framework) • Seam for Apache • Jolira Tools Wicket (powers mobile.walmart.com) • WiQuery • Visural Wicket (standalone Wicket components) (JQuery integration library)
  • 53. Apache Wicket projects • Core • Velocity • Extensions • Auth/Roles • Quick start • JMX • IoC • Dev utils • Spring • Guice • Examples • DateTime
  • 54. Wicket Stuff projects • progressbar • shiro-security • theme • datatable-autocomplete • gae-initializer • yav • flot • push-jdk-1.5 • maven-support • googlecharts • jasperreports • plugin • scala-extensions • mbeanview • input-events • openlayers • jsr303 • javaee-inject • gmap2 • client-and-server-validation • push • inmethod-grid • multi-text-input • wicket-html5 • minis • prototype • wicket-servlet3 • phonebook • simile-timeline
  • 58. Running quickstart $ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket - DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5- SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject - DarchetypeRepository=https://repository.apache.org/content/repositories/ snapshots/ -DinteractiveMode=false _
  • 59. Running quickstart $ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket - DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5- SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject - DarchetypeRepository=https://repository.apache.org/content/repositories/ snapshots/ -DinteractiveMode=false [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] ----------------------------------------------------------- [INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) >>> [INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) <<< [INFO] --- maven-archetype-plugin:2.0:generate (default-cli) --- [INFO] Generating project in Batch mode [INFO] Archetype defined by properties [INFO] ----------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] ----------------------------------------------------------- [INFO] Total time: 1.279s [INFO] Finished at: Fri Feb 04 22:04:14 CET 2011 [INFO] Final Memory: 9M/81M [INFO] -----------------------------------------------------------
  • 61. Running quickstart $ mvn jetty:run [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building quickstart 1.0-SNAPSHOT [INFO] ----------------------------------------------------------- [INFO] Starting jetty 7.2.2.v20101205 ... 2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205 2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo INFO - WebXmlFile - web.xml: found filter with na INFO - Application - [wicket.myproject] init: Wick INFO - RequestListenerInterface - registered listener interface INFO - WebApplication - [wicket.myproject] Started Wi ****************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. *** *** ^^^^^^^^^^^ *** *** Do NOT deploy to your live server(s) without changing this.*** *** See Application#getConfigurationType() for more information*** ****************************************************************** 2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
  • 63. Quick start alternative Leg up • Spring • Guice • JDBC • JPA • Hibernate • Scala http://jweekend.com/dev/LegUp
  • 64. Want to learn more?
  • 65. Want to learn more?
  • 66. Want to learn more? http://wicket.apache.org/learn/books.html
  • 72. Hello, World! <h1 wicket:id="msg">[Replaced text]</h1> + add(new Label("msg", "Hello, World!"));
  • 73. Hello, World! <h1 wicket:id="msg">[Replaced text]</h1> + add(new Label("msg", "Hello, World!")); = <h1>Hello, World!</h1>
  • 75. This link has been clicked 123 times
  • 76. This link has been clicked 123 times This link has been clicked 123 times!
  • 77. This link has been clicked 123 times This <a href="#">link</a> has been clicked 123 times!
  • 78. This link has been clicked 123 times This <a href="#">link</a> has been clicked <span>123</span> times!
  • 79. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span>123</span> times!
  • 80. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span wicket:id="clicks">123</span> times!
  • 81. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span wicket:id="clicks">123</span> times!
  • 82. This link has been clicked 123 times public class ClickCountPage extends WebPage { }
  • 83. This link has been clicked 123 times public class ClickCountPage extends WebPage { public ClickCountPage() { } }
  • 84. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { } }
  • 85. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { add(new Link<Void>("link") { public void onClick() { clicks++; } }); }
  • 86. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { add(new Link<Void>("link") { ... }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks"))); } }
  • 88. 2 modes for your app Development and Deployment
  • 89. Development mode $ mvn jetty:run [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building quickstart 1.0-SNAPSHOT [INFO] ----------------------------------------------------------- [INFO] Starting jetty 7.2.2.v20101205 ... 2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205 2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo INFO - WebXmlFile - web.xml: found filter with na INFO - Application - [wicket.myproject] init: Wick INFO - RequestListenerInterface - registered listener interface INFO - WebApplication - [wicket.myproject] Started Wi ****************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. ** *** ^^^^^^^^^^^ ** *** Do NOT deploy to your live server(s) without changing this. ** *** See Application#getConfigurationType() for more information ** ****************************************************************** 2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
  • 90. Development mode • exceptional error pages • dynamic markup reloading • no caching • no javascript/css optimizations • discover mistakes early (serialization, missing components, ...) • Wicket debugger visible
  • 91. Deployment mode • Cache markup resources • No checks • Don’t display stack traces to users • Minimize/compress JavaScript • Don’t generate wicket tags • Wicket debugger not visible
  • 92. FREE PRO TIP: Don’t perform your performance tests in development mode!
  • 95. Ajax envelope <?xml version="1.0" encoding="UTF-8"?> <ajax-response> <component id="count2"> <![CDATA[<span wicket:id="count" id="count2">1</span>]]> </component> </ajax-response>
  • 96. Error message Unable to find component with id 'count' in HomePage. This means that you declared wicket:id=count in your markup, but that you either did not add the component to your page at all, or that the hierarchy does not match.
  • 99. WicketTester • Test components directly, or their markup • Runs tests without starting server • Ajax testing (server side) • Runs in IDE, ant, maven builds • Achieves high code coverage
  • 100. Testing Hello, World! @Test public void rendersWelcomeMessage() { }
  • 101. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); }
  • 102. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorldPage.class); }
  • 103. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorldPage.class); tester.assertLabel("msg", "Hello, World!"); }
  • 104. Testing Click Count @Test public void clicksIncreaseCount() { }
  • 105. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); }
  • 106. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); }
  • 107. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); }
  • 108. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); tester.clickLink("link"); }
  • 109. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); tester.clickLink("link"); tester.assertModelValue("clicks", 1); }
  • 110. Other test frameworks • PageTest (by Kent Tong) • JDave (BDD framework)
  • 111. Summary • Widely used • Component oriented • Java • Open Source (ASL 2.0)
  • 114. Pre 1.5 • Checks for valid markup don’t accept new field types • HTML 5 defines: <input type=”text|email|password|number|date| search|url|...”>
  • 115. Wicket 1.5 • EmailTextField • NumberTextField • UrlTextField • RangeTextField
  • 117. Split up core library • Old: • wicket.jar
  • 118. Split up core library • Old: • wicket.jar • New: • wicket-requests.jar • wicket-util.jar • wicket-core.jar
  • 119. Maven users <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-core</artifactId> <version>1.5-RC1</version> </dependency>
  • 121. Wicket < 1.5 • Decoding request and handling in state machine • Debugging ‘interesting’ • Designed for flexibility • Served its purpose—took on 4 years of engineering
  • 122. Wicket 1.5 • Request cycle processing completely rewritten • Rendering code has been improved and simplified • URL rendering simplified: now in one place
  • 123. Wicket < 1.5 • Custom request cycle: subclass WebRequestCycle • Problematic with add-ons: • HibernateRequestCycle • SecureRequestCycle • ActivityRequestCycle
  • 124. New: RequestCycleListener public interface IRequestCycleListener { void onBeginRequest(RequestCycle cycle); void onEndRequest(RequestCycle cycle); void onDetach(RequestCycle cycle); IRequestHandler onException(RequestCycle cycle, Exception ex); }
  • 125. RequestCycleListener public class SomeWebApplication extends WebApplication { @Override protected void init() { } @Override public Class<? extends Page> getHomePage() { return SomePage.class; } }
  • 126. RequestCycleListener public class SomeWebApplication extends WebApplication { @Override protected void init() { addRequestCycleListener(new IRequestCycleListener() { public void onBeginRequest() { // do something at the beginning of the request } public void onEndRequest() { // do something at the end of the request } public void onException(Exception ex) { // do something here when there's an exception } }); } @Override public Class<? extends Page> getHomePage() { return SomePage.class; } }
  • 128. Switching to HTTPS public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); } }
  • 129. Switching to HTTPS @RequireHttps public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); } }
  • 130. Switching to HTTPS @RequireHttps public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); setRootRequestMapper( new HttpsMapper(getRootRequestMapper(), new HttpsConfig()); } }
  • 132. Component event bus • IEventSource: objects that send events <T> void send(IEventSink sink, Broadcast broadcast, T payload); • IEventSink: objects that receive events void onEvent(IEvent<?> event); • Participants: Components, RequestCycle, Session and Application
  • 133. Event bus example Ajax link counter
  • 134. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new Link<Void>("link") { @Override public void onClick() { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks"))); } }
  • 135. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new Link<Void>("link") { @Override public void onClick() { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 136. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 137. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 138. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 139. Pre-event bus • Link needs to know the updatable components • Makes code brittle, hard to maintain • Better: • Let the label refresh itself with each Ajax request
  • 140. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 141. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; send(getPage(), Broadcast.BREADTH, target); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  • 142. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; send(getPage(), Broadcast.BREADTH, target); } }); add(new CountLabel("count", new PropertyModel<Integer>(this, } }
  • 143. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { } }
  • 144. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); } } }
  • 145. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } } }
  • 146. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } @Override public void onEvent(IEvent<?> event) { super.onEvent(event); } } }
  • 147. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } @Override public void onEvent(IEvent<?> event) { super.onEvent(event); if (event.getPayload() instanceof AjaxRequestTarget) { AjaxRequestTarget target = (AjaxRequestTarget) event.getPayload(); target.add(this); } } } }
  • 148. Post-event bus • A bit more code • Updates are now completely decoupled • Make the payload type safe and meaningful: no AjaxRequestTarget, but CountEvent • AJAX requests trigger a default event with an AjaxRequestTarget as payload
  • 149. And much, much more: http://cwiki.apache.org/WICKET/ migration-to-wicket15.html
  • 150. Thank you! Questions? Ask!

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. refresher course voor Wicket\n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. quickstart, leg before wicket, projecten en boeken\n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. - debug mode voor quick turnaround\n - jrebel\n - markup reloading\n - markup/js/css in package structuur\n - development mode: excellente excepties, andere tools voor ontwikkelaars\n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. - wicket tester\n - jdave\n - page test (kent tong?)\n - cucumber wicket\n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n