560 likes | 958 Views
Apache Wicket. Gerolf Seitz. Web Development with just Java. and a little bit of HTML. Gerolf Seitz. Since Sept.07 Committer PMC MSc student (almost finished) Software Engineer at Software Competence Center Hagenberg GmbH , Upper Austria. Agenda. What is Wicket? Core Concepts
E N D
Apache Wicket Gerolf Seitz
Web Development withjust Java and a little bit of HTML
Gerolf Seitz • Since Sept.07 • Committer • PMC • MSc student (almost finished) • Software Engineer at Software Competence Center Hagenberg GmbH, Upper Austria
Agenda • What is Wicket? • Core Concepts • Developing a custom Component • Summary • Q&A
Agenda • What is Wicket? • Core Concepts • Developing a custom Component • Summary • Q&A
Wicket in a Nutshell • Open Source • Component oriented • Web application framework • Java + HTML
Features • Everything in Java • State management • Safe URLs • Nice URLs (mounting) • OOTB support for • Clustering • Portlet
Features • Reusable components • Nested forms • No more double submit of forms • Back-button-support • I18n • WicketTester
Features • Ajax "without" JavaScript • Header Contributions • JavaScript & CSS • Component level security
Hello, World! <h1 wicket:id="msg">[text goes here]</h1>
Hello, World! <h1 wicket:id="msg">[text goes here]</h1> + add(new Label("msg", "Hello, World!"));
Hello, World! <h1 wicket:id="msg">[text goes here]</h1> + add(new Label("msg", "Hello, World!")); = <h1>Hello, World!</h1>
Hello, World! <h1 wicket:id="msg">[text goes here]</h1> + add(new Label("msg", "Hello, World!")); = <h1>Hello, World!</h1>
Hello, World! <h1 wicket:id="msg">[text goes here]</h1> + add(new Label("msg", "Hello, World!")); = <h1>Hello, World!</h1>
Brief History • 2004: The First Encounter • 2005: JavaOne'05 Smackdown • 2006: Incubation at ASF
Brief History • 2007: Graduation • 2007: 1.3 released • 2007: WUGs start spawning Amsterdam meetup: 80 attendees
Projects • core • extensions • ioc (spring, guice) • date/time • velocity • jmx
Getting Wicket Current Release: 1.3.3 <dependency groupId="org.apache.wicket" artifactId="wicket" version="1.3.3" />
Getting Wicket - Quickstart http://wicket.apache.org/quickstart.html
Agenda • What is Wicket? • Core Concepts • Developing a custom Component • Summary • Q&A
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
Application • Main entry point • Initialization • Configuration • Factories • Homepage • Configured in web.xml
Application <filter> <filter-name>wicket</servlet-name> <filter-class> org.apache.wicket.protocol.http.WicketFilter </filter-class> <init-param> <param-name>applicationClassName</param-name> <param-value>example.MyApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </filter>
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
Session • Abstraction of a user session • Stores session specific data • Strongly typed session attributes
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
RequestCycle • Stateful • Tied to specific user session • Not (typically) bookmarkable • Stateless • Not necessarily tied to specific user session • Bookmarkable
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
Components • Basic building blocks • Encapsulate the programmatic manipulation of markup • Render content • Receive events • onClick, onSubmit
Components – lots of `em • Label, MultiLineLabel, TextField, PasswordTextField, Image, Link, AjaxLink, AjaxFallbackLink, Button, AjaxButton, DatePicker, ListView, RefreshingView, DataGrid, DataTable, Tree, GMap, Wizard, JasperReports, ...
Components • Component has wicket:id • Same wicket:id in markup • Hierarchy must match <h1 wicket:id=„msg“>[gets replaced]</h1> new Label(„msg“, „Hello World!“);
Component: Link <a href="#" wicket:id="link">Click</a> Link link = new Link("link"); add(link);
Component: Link <a href="#" wicket:id="link">Click</a> Link link = new Link("link") { @Override public void onClick() { //do something setResponsePage(new NewPage()); } }; add(link);
Component: AjaxLink <a wicket:id="link">Click</a> AjaxLink link = new AjaxLink("link") { public void onClick(AjaxRequestTarget t){ //do something } }; add(link);
Component: AjaxLink <a wicket:id="link">Click</a> someComponent.setOutputMarkupId(true); AjaxLink link = new AjaxLink("link") { public void onClick(AjaxRequestTarget t){ //do something t.addComponent(someComponent); t.appendJavascript("Effects.fade('foo');"); } }; add(link);
Components • Components with own markup • Page, Panel, Border • Java and markup files in same package on classpath
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
Behaviors • Plugins for components • Change attributes of your component‘s markup • Add Javascript events • Add Ajax behavior timeLabel.add( new AjaxSelfUpdatingTimerBehavior( Duration.seconds(5)));
Behaviors link.add(new AbstractBehavior() { public void onComponentTag(Component component, ComponentTag tag) { tag.put("onclick", "return confirm('Are you sure?');"); } }); Output: <a href="..." onclick="return confirm('...');">...</a>
Core Concepts • Application • Session • RequestCycle • Components • Behaviors • Models
Models • Bind POJO's to Wicket components new Label("name", model) <<Person> +name: String +city: String Model
Models • Lazy binding in Java sucks • Doesn't update: • new Label("name", person.getName()); • Null checks necessary • new Label("street", person.getAddress().getStreet()); • Solution: OGNL/EL like expressions
Models • PropertyModel: • new PropertyModel(person, “name”) • new PropertyModel(person, “address.street”) • CompoundPropertyModel • setModel(new CompoundPropertyModel(p)); • add(new Label("name")); • add(new Label("address.street"));
Agenda • What is Wicket? • Core Concepts • Developing a custom Component • Summary • Q&A
Custom Components • Eelco Hillenius: « Imagine being told that you can use Java as your programming language, but at the same time being told not to create your own classes. [...] I fail to understand why that has to be different for UI development, and Wicket proves it doesn't have to be so. »
PasswordStrenghIndicator <html> <head> <title>Insert title here</title> <wicket:head> <wicket:link> <link rel="stylesheet" type="text/css" href="res/PasswordField.css"/> </wicket:link> </wicket:head> </head> <body> <wicket:panel> <input wicket:id="password" type="password" /><span wicket:id="strength">[strengthbar]</span> </wicket:panel> <div> <hr/> Examples:<br/> <input type="password" /><span class="weak"> </span> (weak)<br/> <input type="password" /><span class="medium"> </span> (medium)<br/> <input type="password" /><span class="strong"> </span> (strong)<br/> </div> </body> </html>
PSI - Markup <wicket:head> <wicket:link> <link rel="stylesheet" type="text/css" href="res/PasswordField.css"/> </wicket:link> </wicket:head> <wicket:panel> <input wicket:id="password" type="password" /> <span wicket:id="strength">[strengthbar]</span> </wicket:panel>
PSI - Java publicclass PasswordField extends Panel { publicfinalstatic String WEAK = "weak"; publicfinalstatic String MEDIUM = "medium"; publicfinalstatic String STRONG = "strong"; public PasswordField(String id, IModel model) { super(id, model); PasswordTextField passwordTextField = new PasswordTextField("password", model); add(passwordTextField); final Label strength = new Label("strength", ""); add(strength); strength.add(new AttributeModifier("class", true, new Model() { public Object getObject() { return getPasswordStrength(PasswordField.this.getModelObjectAsString()); } })); strength.setOutputMarkupId(true); passwordTextField.add(new OnKeyPausedAjaxBehavior() { protectedvoid onUpdate(AjaxRequestTarget target) { target.addComponent(strength); } }); }}
PSI - TestPage publicclass TestPage extends WebPage { private String password; public TestPage() { Form form = new Form("form"); form.add(new PasswordField("password", new PropertyModel(this, "password"))); add(form); } }
Agenda • What is Wicket? • Core Concepts • Developing a custom Component • Summary • Q&A