Enjoying Web Development with Wicket By Kent Ka Iok Tong Copyright © 2015 TipTec Development

Publisher:

TipTec Development

Author's email: [email protected] Book website:

http://www.ttdev.com

Notice:

All rights reserved. No part of this publication may be reproduced, stored in a retrieval system or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of the publisher.

ISBN:

978-1-329-49604-0

Edition:

Fourth edition April 2015

Enjoying Web Development with Wicket

3

Foreword How to create web-based applications easily? If you would like to create web-based applications easily, then this book is for you. More importantly, it shows you how to do that with joy and feel good about your own work! You don't need to know servlet or JSP while your productivity will be much higher than using servlet or JSP directly. This is possible because we are going to use a library called Wicket that makes complicated stuff simple and elegant. How does it do that? First, it allows the web designer to work on the static contents and design of a page while allowing the developer to work on the dynamic contents of that page without stepping on each other's toes; Second, it allows developers to work with high level concepts such as objects and properties instead of HTTP URLs, query parameters or HTML string values; Third, it comes with powerful components such as calendar, tree and data grid and it allows you to create your own components for reuse in your own project. However, do not take our word for it! This book will quickly walk you through real world use cases to show you how to use Wicket and leave it up to you to judge.

How this book can help you learn Wicket? •

It has a tutorial style that walks you through in a step-by-step manner.



It is concise. There is no lengthy, abstract description.



Many diagrams are used to show the flow of processing and high level concepts so that you get a whole picture of what is happening.



Free sample chapters are available on http://www.ttdev.com. You can judge it yourself.



The manuscript of book has been used to train up a team of programmers who had not used Java or written any program at all. The training took only a few months (six hours per week). Now they are developing a core application for their organization using Wicket, Spring and Hibernate.

Unique contents in this book This book covers the following topics not found in other books on Wicket: •

Works with Wicket v7 (and v6).

4

Enjoying Web Development with Wicket



Full coverage of JPA/Hibernate and Spring including conversions (extended sessions).



How to make a jQuery UI component into a Wicket component supporting self-contained client-server callbacks.



How to unit test Wicket pages with the Wicket Page Test library (supporting AJAX).

Target audience and prerequisites This book is suitable for those learning how to develop web-based applications and those who are experienced in servlet, JSP, Struts and would like to see if Wicket can make their jobs easier. In order to understand what is in the book, you need to know Java, HTML and some simple SQL. However, you do NOT need to know servlet, JSP, Tomcat, Spring, JPA or Hibernate.

Acknowledgments I would like to thank: •

The Wicket team for creating Wicket.



Helena Lei for proofreading previous versions of this book.



Eugenia Chan Peng U for doing book cover and layout design.

Enjoying Web Development with Wicket

5

Table of Contents Foreword.........................................................................................3 How to create web-based applications easily?..........................3 How this book can help you learn Wicket?................................3 Unique contents in this book......................................................3 Target audience and prerequisites.............................................4 Acknowledgments......................................................................4 Chapter 1 Getting Started with Wicket..........................................11 What's in this chapter?.............................................................12 Developing a Hello World application with Wicket...................12 Installing Eclipse.......................................................................12 Installing Tomcat.......................................................................13 Downloading the jar files easily................................................18 Creating the Hello Word application.........................................20 Installing Wicket........................................................................24 Creating the Hello World page.................................................26 Displaying the Hello World page..............................................30 Generating dynamic content....................................................35 Exact behavior of the Label......................................................38 Common errors in Wicket applications.....................................39 Supporting badly structured HTML files...................................42 Debugging a Wicket application...............................................42 Summary..................................................................................43 Chapter 2 Using Forms.................................................................45 What's in this chapter?.............................................................46 Developing a stock quote application.......................................46 Implementing the OK button.....................................................47 Getting the stock symbol..........................................................51 Using a single tag as a slot......................................................56 Displaying the result page........................................................57 Using a combo box to present the stock symbol.....................58 Displaying a "no selection" entry..............................................60 Inputting a date.........................................................................63 Impact of the preferred language.............................................65 Displaying feedback messages................................................67 Marking input as required.........................................................69 Letting the user choose a date from a calendar......................72

6

Enjoying Web Development with Wicket

Using a DateField.....................................................................76 Summary..................................................................................77 Chapter 3 Using Forms: More Techniques...................................79 What's in this chapter?.............................................................80 Presenting a Size object to the user........................................80 Creating the property models automatically.............................84 Making sure the page is serializable........................................87 What if the input is invalid?.......................................................89 Validating the material code for the furniture............................92 Displaying the error messages in red.......................................95 Displaying invalid fields in red..................................................96 Discovering of the type of the model value..............................99 Enabling validation on condition.............................................100 Validating a combination of multiple input values..................104 Summary................................................................................107 Chapter 4 Creating an e-Shop....................................................109 What's in this chapter?............................................................110 Creating an e-shop.................................................................110 Listing the products.................................................................111 Creating the links to show the product details........................119 Implementing the DetailsPage...............................................122 Implementing a shopping cart................................................125 How Tomcat and the browser maintain the session...............131 Checking out...........................................................................132 Making the DetailsPage bookmarkable..................................132 Using a bookmarkable link for page transition.......................134 Using a non-callback link........................................................136 Not saving the CatalogPage to the session...........................139 Not saving the DetailsPage....................................................140 Persisting the session object..................................................143 Summary................................................................................146 Chapter 5 Creating a Forum.......................................................149 What's in this chapter?...........................................................150 Creating a forum.....................................................................150 Logging in a user....................................................................153 Creating the posting page......................................................154 Checking if the user can post.................................................155 Protecting many pages...........................................................159 Declarative authorization rules...............................................161

Enjoying Web Development with Wicket

7

Implementing the delete post function...................................166 Disabling the Delete button if the user is not authorized.......167 Authorizing access to a component instance.........................169 Allowing users to delete their own posts................................170 Showing the Delete button for authorized users only............171 Checking the authorization when the user clicks Delete.......172 Implementing logout...............................................................180 Summary................................................................................181 Chapter 6 Creating Custom Components..................................183 What's in this chapter?...........................................................184 Displaying the current year.....................................................184 Reusing the logic in multiple pages........................................184 Creating a TimeLabel component..........................................186 Construction time vs. render time...........................................191 Creating a component accepting a child component.............193 Creating a component that handles callbacks.......................196 Creating a component to serve as a reusable form...............197 Creating a component to display an object for editing...........199 Summary................................................................................203 Chapter 7 Building Interactive Pages with AJAX........................205 What's in this chapter?...........................................................206 A simple AJAX page...............................................................206 Implementing the AJAX page.................................................207 Refreshing the result as the user types..................................212 AJAX without form field values...............................................214 Turning the Help button into a link..........................................215 Using HTML code in the help content....................................216 Hiding the help content...........................................................223 Creating a form that changes.................................................223 Using an auto completing text field........................................227 Popping up a dialog................................................................232 Summary................................................................................246 Chapter 8 Using Hibernate/JPA and Spring...............................249 What's in this chapter?...........................................................250 A human resource management system................................250 Setting up a database server.................................................251 Creating an EntityManager.....................................................254 Using an EntityManager.........................................................258 Creating the tables automatically...........................................259

8

Enjoying Web Development with Wicket

Loading an Employee object..................................................260 Storing the EntityManager into the thread.............................263 Saving an Employee object....................................................266 Assigning the ID automatically...............................................272 Many-to-one association........................................................272 Lazy loading of the Set elements...........................................275 The danger with detached entities.........................................278 Using Hibernate and Spring in a web application..................280 Accessing Spring services in Wicket pages...........................283 Marking the service as a service............................................284 Dealing with detached entities in Wicket applications...........285 Demonstrating the lazy loading problem................................291 Implementing the first method: Preloading............................293 Implementing the second method: Reloading........................294 Implementing the third method: Keeping the EntityManager open........................................................................................295 Supporting editing with the first method.................................298 Supporting editing with the third method................................306 Wrapping up the ugly code.....................................................309 Summary.................................................................................311 Chapter 9 Using the DataTable Component...............................315 What's in this chapter?...........................................................316 Searching and displaying the products..................................316 Listing the entries in alternating colors...................................321 Sorting the products...............................................................323 Setting the styles of tool bars.................................................325 Using markups in a cell..........................................................326 Using a lighter alternative to Panel........................................331 Moving the navigator to the bottom........................................333 Customizing the message in the navigation tool bar.............335 Summary................................................................................335 Chapter 10 Supporting Other Languages..................................337 What's in this chapter.............................................................338 How can a page render to different languages......................338 Supporting multiple languages in domain models.................345 Displaying a logo....................................................................352 Translating static text mixed with component slots................356 Translating the SearchProductsPage....................................358 Creating a custom component supporting multiple languages

Enjoying Web Development with Wicket

9

................................................................................................360 Filtering unsupported languages............................................363 Using a model to load the text................................................365 Providing translated text to all pages in a package...............366 Providing global translated text..............................................368 Translating the whole template..............................................368 Letting the user change the locale.........................................369 Changing the locale without the Change button....................375 Summary................................................................................377 Chapter 11 Working with the Back Button..................................379 What's in this chapter?...........................................................380 An incrementing counter........................................................380 What happens if you use the Back button?...........................381 How Wicket could support the Back button...........................381 What if the browser caches and displays the old page anyway? ................................................................................................386 How to allow the user to really go back?................................386 Is the page instance really loaded from the hard disk?.........388 Will changes done in an AJAX request change the page ID? ................................................................................................390 Summary................................................................................391 Chapter 12 Handling File Downloads and Uploads...................393 What's in this chapter?...........................................................394 Downloading a photo..............................................................394 Configuring caching of the resource......................................399 Reading the bytes from other common sources....................401 Generating an resource on the fly..........................................403 Getting the resource from an arbitrary source.......................405 Displaying an image...............................................................407 Making the image bookmarkable...........................................409 Using a resource reference to generate a response.............414 Uploading a photo..................................................................415 Summary................................................................................418 Chapter 13 Providing a Common Layout...................................421 What's in this chapter?...........................................................422 Providing a common layout....................................................422 Two varying parts?.................................................................424 Creating BookmarkalePageLinks automatically.....................427 Summary................................................................................429

10

Enjoying Web Development with Wicket

Chapter 14 Using Javascript......................................................431 What's in this chapter?...........................................................432 Are you sure to delete it?.......................................................432 Reusing the confirm button....................................................435 Using a namespace for the Javascript...................................436 Putting the Javascript into a file.............................................437 Using a jQuery UI widget........................................................439 Loading data from the server side..........................................440 Untangling the Javascript.......................................................444 Turning the jQuery widget into a Wicket component.............449 Summary................................................................................455 Chapter 15 Unit Testing Wicket Pages.......................................457 What's in this chapter?...........................................................458 Unit testing a Wicket page......................................................458 Testing the form submission...................................................466 Testing AJAX functions...........................................................468 Locating Wicket generated elements easily...........................469 Testing without a browser.......................................................472 Replacing a Spring bean with a mocked bean.......................472 Other functions of Wicket Page Test......................................475 Summary................................................................................476 Chapter 16 Deploying a Wicket Application...............................477 What's in this chapter?...........................................................478 Distributing your application...................................................478 Deploying it in Tomcat............................................................479 Putting the application into deployment mode.......................479 Configuring logging.................................................................482 Specifying the database in production...................................484 Switching between multiple sets of configurations................486 Logging the actions of the users............................................490 Summary................................................................................492 References..................................................................................495 Alphabetical Index......................................................................496

11

Chapter 1 Getting Started with  Wicket

Chapter 1 

12

Chapter 1 Getting Started with Wicket

What's in this chapter? In this chapter you will learn how to set up a development environment and develop a Hello World application with Wicket.

Developing a Hello World application with Wicket Suppose that you'd like to develop an application like this:

Installing Eclipse You need to make sure you have a recent version Eclipse installed (in this book v4.3 is used) and it includes support for Java EE (e.g., check if you can switch to the Java EE perspective as shown below). If not, go to http://www.eclipse.org to download the Eclipse IDE for Java EE Developers (e.g., eclipse-jee-keplerSR1-win32-x86_64.zip). Unzip it into a folder such as c:\eclipse. To see if it's working, run c:\eclipse\eclipse.exe and make sure you can switch to the Java EE perspective:

Chapter 1 Getting Started with Wicket

13

Installing Tomcat Next, you need to install Tomcat, which is a platform hosting your web applications: webapp1

webapp2

...

Tomcat

So, go to http://tomcat.apache.org to download a binary package of Tomcat. Download the zip version instead of the Windows exe version. Suppose that it is apache-tomcat-7.0.40.zip. Unzip it into a folder, say c:\tomcat. To verify that it is working, you can try launching Tomcat from Eclipse. To do that, choose Window | Preferences, then choose Server | Runtime Environment:

14

Chapter 1 Getting Started with Wicket

Click Add and choose Apache Tomcat v7.0:

Chapter 1 Getting Started with Wicket

Click Next. You will see:

15

16

Chapter 1 Getting Started with Wicket

Click Browse to choose the folder containing Tomcat (e.g., c:\tomcat) and then click Finish. Now, you have told Eclipse the location of the Tomcat installation. However, Eclipse allows you to run multiple Tomcat instances off this installation, so that, say, each instance could have its own configuration and its own set of web applications. Therefore, to run Tomcat, you need to define a Tomcat instance first. So, in the Java EE perspective, choose the Server window, click the link to create a new Tomcat instance:

You will see:

Chapter 1 Getting Started with Wicket

17

Make sure the server runtime you created above ("Apache tomcat v7.0") is selected. Click Finish to create the Tomcat instance. Finally, choose that instance and click the green button to launch it:

Then you should see some messages in the Console window. If everything is fine, you should see it saying "Server startup in ??? ms":

18

Chapter 1 Getting Started with Wicket

To stop it, you can click the red button next to the green button:

Downloading the jar files easily You are about to download Apache Wicket and add its jar files to your Eclipse project. However, Wicket itself needs jar files from other 3 rd parties so you must download those too. To do that easily, you can use the Maven Integration plugin. Once it is installed, you can tell it download Wicket. Then it will go to the Internet to download Wicket and add its jar files to the classpath of your project. The cool thing is, it will download all jar files needed by Wicket automatically. To install this plugin, choose Help | Install New Software. You will see:

Chapter 1 Getting Started with Wicket

19

Click Add and define a new update site and input the data as shown below. The name is not really important; the location URL is:

If you're using Eclipse 3.6.x or earlier, use this instead: http://m2eclipse.sonatype.org/sites/m2e .

Then choose this m2e site and the available packages on that site will be listed (see below). Choose "m2e - Maven integration for Eclipse":

20

Chapter 1 Getting Started with Wicket

Then continue until you finish the installation. Restart Eclipse as needed.

Creating the Hello Word application Next, in the Project Explorer, right click and choose New | Project. Then choose Maven | Maven Project:

Chapter 1 Getting Started with Wicket

Click Next. You will see:

21

22

Chapter 1 Getting Started with Wicket

Make sure you re connected to the Internet. Click Next and then choose mavenarchetype-webapp, which is a template for web applications:

Chapter 1 Getting Started with Wicket

Click Next. Then fill in the information as shown below:

23

24

Chapter 1 Getting Started with Wicket

The "group ID" of your package/project. It presents the organization that created the package. It is like package name in Java.

The "artifact ID" of your package/project. It is the name of the application, or like a class name in Java.

Click Finish.

Installing Wicket Now, right click the project and choose Maven | Add Dependency. Enter the "wicket-core" as the keyword to search for the packages (see below). It could take a while. Then choose the latest 7.x version (7.0.0 is used in this book):

Chapter 1 Getting Started with Wicket

25

Enter the keyword here.

Then the Maven plugin will download all the jar files in Apache Wicket and those it needs from a central repository. To verify that, check the presence of the jar files as shown below:

Also note the slf4j-api-1.7.12.jar file below those Wicket jar files. It is the slf4j (simple logging facade for Java) API. At runtime Wicket will perform some

26

Chapter 1 Getting Started with Wicket

logging using this API. The slf4j API works with many different implementations such as log4j or JDK logging. To specify which implementation to use (e.g., log4j), add a new Maven dependency: Group ID

org.slf4j

Artifact ID

slf4j-log4j12

Version

You MUST use the same version as the slf4j-api.jar file. For example, in this case, use 1.7.12.

By the way, what if you added a wrong dependency? You could open the pom.xml file in the project root folder (choose the pom.xml tab to see it in pure text form as required), then delete the dependency manually: 4.0.0 com.foo myapp war 0.0.1-SNAPSHOT myapp Maven Webapp http://maven.apache.org junit junit 3.8.1 test org.apache.wicket wicket-core 7.0.0 org.slf4j slf4j-log4j12 1.7.12 myapp

Creating the Hello World page Now, you will create the Hello World page. In Wicket, each page is implemented by two files: One is .java file (e.g., HelloPage.java) and the other is an HTML file (e.g., HelloPage.html) and they must be in the same Java package (e.g., com.foo.myapp) and have the same base name ("HelloPage" in this case). To do that, create a new folder named "java" in the src/main folder:

Chapter 1 Getting Started with Wicket

27

You will put your Java source files in this folder. The Maven plugin will automatically recognize it as a Java source folder:

28

Chapter 1 Getting Started with Wicket

Next, create the HelloPage.java class in the com.foo.myapp package in this source folder. Input the content like this:

This WebPage class is provided by Wicket. It means your HelloPage class represents a web page.

Next, create a HelloPage.html file in the same folder as HelloPage.java:

Chapter 1 Getting Started with Wicket

Click Finish and then input the content like this:

29

30

Chapter 1 Getting Started with Wicket

The content is simply some HTML code.

They must be in the same folder.

Displaying the Hello World page Now your page is done! How to display it? Create a class MyApp in the same package:

This WebApplication class is provided by Wicket. It means your MyApp class represents a web application.

You may notice that MyApp is marked as in error. This is because it must implement an abstract method. To do that, click the line in error, press Ctrl-1 and choose "Add unimplemented methods" to add the method:

Chapter 1 Getting Started with Wicket

31

Then fill in the code: package com.foo.myapp; import org.apache.wicket.Page; import org.apache.wicket.protocol.http.WebApplication; public class MyApp extends WebApplication { @Override public Class getHomePage() { return HelloPage.class; } }

The HelloPage class (page) is the home page of this application, i.e., it is the default page of the application.

Next, modify the web.xml file in src/main/webapp/WEB-INF with the following content. This file is called the "deployment descriptor": Archetype Created Web Application WicketFilter org.apache.wicket.protocol.http.WicketFilter applicationClassName com.foo.myapp.MyApp Tell Wicket that com.foo.myapp.MyApp is the class of your web application. This way, WicketFilter it will create an instance of this class. Later, /app/* when Wicket needs to display the home page, it will ask that instance for the home page class.

Apart from the applicationClassName parameter, you can ignore the meaning of

32

Chapter 1 Getting Started with Wicket

the rest for now. To make this application run in your Tomcat instance, right click that instance and choose "Add and Remove":

You will see:

Chapter 1 Getting Started with Wicket

33

Choose myapp and click Add to add it to that Tomcat instance. Click Finish. Now, start that Tomcat instance. Check the messages in the Console window to make sure that there is no error. If there is any error and you cannot figure out why, you may contact me at [email protected]. If everything is fine, you should see a message warning you that Wicket is running in development mode:

34

Chapter 1 Getting Started with Wicket

This is perfectly fine and the warning can be safely ignored. To run your application, open a browser and try going to http://localhost:8080/myapp/app. You should see:

What does this URL mean? It is interpreted this way:

Chapter 1 Getting Started with Wicket

35

When Tomcat receives this request, it finds that this part matches your project name. So, it will send the request to your application for processing.

http://localhost:8080/myapp/app When your application receives the request, it finds that this path matches the /app/* pattern so it will send the request to Wicket for processing. As you are not saying which page to display, Wicket will assume that you want the home page.

Archetype Created Web Application WicketFilter org.apache.wicket.protocol.http.WicketFilter applicationClassName com.foo.myapp.MyApp WicketFilter /app/*

When Wicket needs to display the HelloPage, it simply creates a Java object instance from the HelloPage class using the "new" operator in Java and asks it to generate HTML code (see below). That Java instance will simply locate the HelloPage.html file in the same package and output the HTML code inside: 1: Render yourself.

HelloPage Java object

2: Locate the HTML file and output its content. HelloPage.html

Hello world

Generating dynamic content Displaying "Hello World" is not particularly interesting. Next, you will generate the message dynamically in Java. The idea is that, you put a slot in the HTML file and let a so-called component (a Java object) send its output (some HTML

36

Chapter 1 Getting Started with Wicket

code) to fill in that slot at runtime: HelloPage Java object

HelloPage.html

Component

Hello [slot 1]

At rumtime when the HelloPage needs to generate HTML code, it will ask this component to output some HTML code into the slot.

What if there are multiple slots in the HTML file (see below)? For each slot you need a separate component. To link each component to each slot, you assign a unique ID (called the component ID) to each component and the corresponding slot: HelloPage Java object

Component "a"

HelloPage.html

Hello [slot b] ... [slot a]

Component "b"

Because the HTML file is containing some static code (output as is) and some slots, it is called the template for the HelloPage. To implement these ideas, modify HelloPage.html as: Hello world

is just a regular HTML element. It is used to enclose a section of HTML code. To turn it into a slot, as a first attempt, you could assign a special attribute to the like: Hello world

However, in HTML only the follow attributes are allowed to appear in the tag: id, class, style and etc., so it is illegal to put a slotid attribute there. To solve the problem, note that, more strictly speaking, the HelloPage.html file should really read:

Chapter 1 Getting Started with Wicket

37

Use http://www.w3.org/1999/xhtml as the default namespace in the rest of the file.

It is an XML document.

It needs a DOCTYPE declaration. You can ignore its meaning.

Hello world

As these tags do not have any prefix, they are referring to the and tags defined in the XHTML namespace.

This is the XHTML namespace. Although a namespace looks like a web page address, it is just used as unique ID. If you try accessing it in a browser, you may get a "page not found" error.

This more strict version is the so-called XHTML standard. A good thing about XHTML is that people can introduce tags and attributes from other namespaces without making the document invalid. So, to introduce a slotid attribute, one could use a new namespace: http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd

attribute: slotid allowed: for any element

Defines a prefix called "wicket". It is used as a shorthand for the namespace http://wicket.apache.org/dtds.data/wicketxhtml1.4-strict.dtd in the rest of this file.

Hello world Use the "wicket" prefix to indicate that this slotid attribute belongs to the http://wicket.apache.org/dtds.data/wicketxhtml1.4-strict.dtd namespace.

Finally, for simplicity, the attribute is named "id" instead of "slotid". So, the final and working version is: Hello world

38

Chapter 1 Getting Started with Wicket

Next, create a component in the page object: Create a Label component. A Label component will simply output a String as is into the slot.

HelloPage

package com.foo.myapp; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label;

Component "subject"

public class HelloPage extends WebPage { public HelloPage() { Label s = new Label("subject", "John"); add(s); This is the String } to be output. The component ID is } Add the Label component to the Hello page.

"subject".

Now run the application and you will see:

As you can see, HelloPage.html is acting as a template for the Hello page. Each dynamic part in the page is like a blank to be filled in and you just mark each one with the wicket:id attribute. So HelloPage.html is called the template or markup for the Hello page.

Exact behavior of the Label Now, the Label component is outputting the string "John" to fill in the slot. But which of the following is the case?

Chapter 1 Getting Started with Wicket

39

Hello world John Component "subject"

Hello world John Component "subject"

By default, it is the latter. That is, the Label component will keep the start tag () and end tag () for the slot, while replacing the element body with the specified string. Why? For example, you do not have to use a element as the slot. You could be using a element, then definitely you would hope the tag to remain: Hello world John Component "subject"

Common errors in Wicket applications A very common error in Wicket applications is that for example, you have a slot in the template and have created the corresponding component in Java but have forgotten to add it to the page:

40

Chapter 1 Getting Started with Wicket

Hello world

public class HelloPage extends WebPage { public HelloPage() { Label s = new Label("subject", "John"); add(s); } } Forget to add it to the page!

Then when you run the application, seeing a slot with the ID of "subject", Wicket will try to find a component with the ID of "subject" to fill in the slot but fail. So, you will get an "unable to find component" error (shown below). Whenever you see this exception, check if you have really added the component to the page.

The offending slot is highlighted.

Another very common error is the opposite: You have added the component to the page but forgotten to add wicket:id to the slot in the template:

Chapter 1 Getting Started with Wicket

41

Hello world Forget to mark it as a slot!

public class HelloPage extends WebPage { public HelloPage() { Label s = new Label("subject", "John"); add(s); } }

Now when you run it, as there is no slot to fill in, in principle Wicket will not see anything wrong. However, it goes one step further to see if every component in the page has rendered. In this case, the "subject" component will have not been rendered. So, Wicket will trigger a "component failed to render" error (shown below), warning you that you probably have a component but not a corresponding slot:

The offending component is listed here.

Now, undo the changes to make sure the code still works.

42

Chapter 1 Getting Started with Wicket

Supporting badly structured HTML files Your HelloPage.html file is nicely structured as it has proper namespace declarations, every start tag (e.g., ) has a corresponding end tag (): Hello world

But in practice, a lot of HTML files are badly formatted. For example, they be look like: Hello world

That is, even the tag is missing and for the tag, there is no end tag at all! For Wicket to work with such files, Wicket does not insist on having a namespace declaration for the Wicket namespace. Instead, as long as you use wicket:id as the attribute, it will take it as a slot. It means that you could modify HelloPage.html as: Hello world

Or even as: Hello world

The application will continue to work.

Debugging a Wicket application To debug your application in Eclipse, just set a breakpoint as usual:

A breakpoint has been set here.

Instead of clicking the red button the launch Tomcat, click the button that looks

Chapter 1 Getting Started with Wicket

43

like a bug (so to launch Tomcat in debug mode):

Start Tomcat in debug mode.

Now go to the browser to load the page again. Eclipse will stop at the breakpoint:

Then you can step through the program, check the variables and whatever. To stop the debug session, stop Tomcat as usual (the red button).

Summary To create a Wicket application, you create a project from the Maven web

44

Chapter 1 Getting Started with Wicket

application template and then add Wicket as a dependency. Each page in a Wicket application is implemented by two files: a Java class and its template. When a page needs to render, it will look into its own package to find its template with the same base name. The template contains static text plus zero or more slots. You can turn any element into a slot by putting the component ID into the wicket:id attribute. For each slot, the page object will use the component ID to find the corresponding component and tell it to output HTML code to fill into that slot. A Wicket application must contain an application class. Its major purpose is to tell Wicket which is the Java class for the home page. How does Wicket know which class is the application class? You do it in web.xml. A request to display a page is first received by Tomcat. Tomcat will route it to the concerned web application. The web application will then route it to Wicket. Wicket will create a new page object and will route the request to it. A Label component is a very simple kind of component: It will simply output the string that you specified as the HTML code into the body of the slot element, without changing the start tag and end tag of the slot. A common error in Wicket applications is that you have a slot in the template and have indeed created the component but forgotten to add the component to the page. This will result in the "component not found" error. Another common error is the opposite: You have added the component to the page but forgotten to add wicket:id in the template to make it a slot. This will result in a "component failed to render" error. To debug a Wicket application, set a breakpoint in the Java code and launch Tomcat in debug mode.

45

Chapter 2 Using  Forms

Chapter 2 

46

Chapter 2 Using Forms

What's in this chapter? In this chapter you'll learn how to use forms to get input from the user.

Developing a stock quote application Suppose that you'd like to develop an application like this:

That is, the user can enter the stock symbol (MSFT is the displayed as the default) and click OK, then the stock value will be displayed. Now, let's do it. First, copy the myapp project and paste it as a project named "quote". However, Eclipse will fail to update some internal settings, so you need to give it a hand: choose Window | Show View | Navigator and then open the file as shown below:

Change all occurrences of "myapp" to "quote" and then save the file. Similarly, do the same thing in pom.xml: 4.0.0 com.foo quote war 0.0.1-SNAPSHOT quote Maven Webapp

Chapter 2 Using Forms

47

http://maven.apache.org ... quote


Then, rename the com.foo.myapp package as com.foo.quote. Delete HelloPage.java and HelloPage.html.

Implementing the OK button Now, let's first create the page with just the OK button. Once the button is clicked, for simplicity, the application will just print a "clicked" message to the console and then display the page again. To create such a page, the HTML code should contain a
and a :


The key is, how to regain control when the user clicks the button to submit the form. To do that, you need to set the action attribute of the
. To do that, turn the element into a slot (see the diagram below). On render, the corresponding component should insert the action attribute into the tag to invoke the onSubmit() method of this component itself in this page instance. In order to allow Wicket to locate this page instance, the page instance must have a unique ID (3 in this example):

48

Chapter 2 Using Forms

Conceptually, this URL will tell Wicket (/app) to invoke the onSubmit() method of the component named "f" in the page instance whose ID of 3. Note that this is not really the actual format used by Wicket, but is conceptually similar.

...


Page 3

Component "f"

class Component { void onSubmit() { ... } }

After invoking the onSubmit() method to handle the call back, how to generate the HTML code as the response? By default, Wicket will ask that page instance handling the call back to render again. So, you will see the same page. To implement these ideas, what kind of component should you use? Obviously you can't use a Label component as it can only set the body of the slot element but can't add an action attribute and doesn't handle form submissions. To do all these, you use a Form component. So, create a QuoteInputPage class and QuoteInputPage.html in the com.foo.quote package:

Chapter 2 Using Forms

49

QuoteInputPage.html

This is just a normal HTML submit button.

Use a Form component. The variable name doesn't have to be the same as the component ID ("f"). It can be anything.

What's the meaning of Void? It will be explained later in the chapter. Don't worry about it for now.

QuoteInputPage.java

... import org.apache.wicket.markup.html.form.Form; public class QuoteInputPage extends WebPage { public QuoteInputPage() { Form form = new Form("f") { @Override protected void onSubmit() { System.out.println("clicked"); } Instead of calling a listener object, }; it will call its own onSubmit(). Here add(form); you override it to receive control. } As always, you need to add the } component to the page.

Set it as the home page by modifying MyApp: package com.foo.quote; ... public class MyApp extends WebApplication { @Override public Class getHomePage() { return QuoteInputPage.class; } }

Modify web.xml to update the package name of the MyApp class: Archetype Created Web Application 2 WicketFilter org.apache.wicket.protocol.http.WicketFilter applicationClassName com.foo.quote.MyApp ...

Add the project to the Tomcat instance. Go to http://localhost:8080/quote/app and you should see:

50

Chapter 2 Using Forms

Click the OK button. You should see the message in the Console window and then the page is displayed again:

To verify that a single page instance is used, modify the code: public class QuoteInputPage extends WebPage { public QuoteInputPage() { System.out.println("Constructing page " + getPageId() + " at address " + getPageAddress()); Form form = new Form("f") { @Override protected void onSubmit() { System.out.println("clicked. Handled by page " + getPageId() + " at address " + getPageAddress()); } }; add(form); } private int getPageAddress() { return hashCode(); // usually the hash code is the address } }

Save the file and wait until Tomcat finishes reloading the application. By the way, you may also see exceptions like below. Don't worry. It is harmless and later you will learn why that is happening.

Chapter 2 Using Forms

51

Now, run the application and click the button a few times. In the Console window you can verify that a single page was created and constructed exactly once but has been used repeatedly to handle the clicks: Constructing page 0 clicked. Handled by clicked. Handled by clicked. Handled by

at address 665063176 page 0 at address 665063176 page 0 at address 665063176 page 0 at address 665063176

Now, undo the changes to the code to keep it clean.

Getting the stock symbol Next, let's move on to get the stock symbol. To have a text field, there should be an element inside the
element (see the diagram below). How to let it display the "MSFT" as the default value? Let's imagine that there is a new kind of component called TextField component that can output any String you specify (here, you'll specific "MSFT") as the value attribute at runtime on render: value="MSFT"



Page

TextField "sym"

display value

"MSFT"

In Java code, conceptually you might write something like (do not actually do it in Eclipse as it is NOT really working code):

52

Chapter 2 Using Forms

public class QuoteInputPage extends WebPage { private String s = "MSFT"; The String

public QuoteInputPage() { value to be Form form = new Form("f") { displayed ... }; add(form); TextField sym = new TextField("sym", s); ... } }

However, what happens if the user inputs "IBM" in the text field and submits the form? Then the TextField component should store the new value ("IBM") to somewhere for you to use. It could change the String in place if the String class in Java had a method to change its character content: s QuoteInput Page

"MSFT" public class TextField { private String val; public TextField(String id, String val) { this.val = val; Let's assume that this } method will take

val

control on form public onSubmit() { val.setChars("IBM"); submissions. }

}

No such method!

TextField The TextField wanted to overwrite the content with "IBM" but to no avail.

The most it could do is to change its own "val" variable to point to another String, while the original String remains unchanged:

Chapter 2 Using Forms

s

53

The caller is, sadly, still referring to the original String.

QuoteInput Page

"MSFT"

"IBM"

public class TextField { private String val; public TextField(String id, String val) { this.val = val; } val

public onSubmit() { val = "IBM"; }

TextField

}

Obviously this will not cut it. To solve the problem, the object containing the data (to be displayed to the user for editing) must be both readable and writable, unlike a String which is readable but not writable. Such an object is called a Model in Wicket. You can roll one up easily: public class Model { private String v; public String get() { return v; } public void set(String val) { v = val; }

s QuoteInput Page

"v", the content of the model, can be changed easily.

v Model

"MSFT"

} "IBM" public class TextField { private Model val; public TextField(String id, Model val) { this.val = val; }

val TextField

public onSubmit() { val.set("IBM"); } }

In fact, the Model class does not have to keep a String as the content; it could keep an Integer, a Date, or any other type of object: public class Model { private T v; public T get() {

54

Chapter 2 Using Forms

return v; } public void set(T val) { v = val; } }

Of course, Wicket already provides such a class to you, so you do not need to write it yourself. Instead, use it directly in the QuoteInputPage class: ... import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.Model; Set the initial value. public class QuoteInputPage extends WebPage { private Model s = new Model("MSFT"); public QuoteInputPage() { Form form = new Form("f") { @Override protected void onSubmit() { System.out.println("clicked"); } }; add(form); TextField sym = new TextField("sym", s); } } Similarly, the TextField could display an Integer or a Date in addition to a String. So, you must specify the type here.

Provide the model to the TextField component so that it can store the user input into the model.

Now, it is almost done, but you have not added the TextField component to the page yet. Should you do it as shown below? public class QuoteInputPage extends WebPage { private Model s = new Model("MSFT"); public QuoteInputPage() { Form form = new Form("f") { ... }; add(form); TextField sym = new TextField("sym", s); add(sym); } }

To see the answer, note that the slot is included in the body of the
slot:


And generally speaking, the slot for a Form component may contain multiple child slots (see the diagram below). When the Form component needs to render itself, as mentioned before, it will add the action attribute to the
tag, but what will it do to the body of the element? Just like a page object, it

Chapter 2 Using Forms

55

should output the static text as is and ask its child components to fill out the child slots: Page

[slot a]...[slot b]
Form

Component "a" Component "b"

Therefore, the "sym" TextField component should be added to the Form component instead of the page. If you add it to the page or somewhere else, the Form component will be unable to find it and you will get the "component not found" error as mentioned before. So, modify the code: public class QuoteInputPage extends WebPage { ... public QuoteInputPage() { Form form = new Form("f") { ... }; add(form); TextField sym = new TextField("sym", s); form.add(sym); } }

To see if the TextField is really storing the symbol into the model, further modify the code:

56

Chapter 2 Using Forms

This method is called after all child components have handled the submission. It means the TextField has set the value into the model.

public class QuoteInputPage extends WebPage { private Model s = new Model("MSFT");

public QuoteInputPage() { Form form = new Form("f") { @Override Instead of having get() and set(), protected void onSubmit() { System.out.println(s.getObject()); the real Wicket Model has getObject() and setObject(), but } the idea is the same. }; add(form); TextField sym = new TextField("sym", s); form.add(sym); } }

Run the application. Observe that MSFT is displayed as the default value:

Change the symbol to IBM and click OK. It should print "IBM" in the Console window: ******************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. *** *** ^^^^^^^^^^^ *** *** Do NOT deploy to your live server(s) without changing this. *** *** See Application#getConfigurationType() for more information. *** ******************************************************************** IBM

And then display the page again. Note that as the model now contains "IBM", the value in the text field will also be "IBM".

Using a single tag as a slot You may have noticed that for the moment, there is a slash to close the tag:

Chapter 2 Using Forms

57

Note the slash.

This makes the tag a complete XML element. However, this is not required in plain HTML. That is, it is OK to write a start tag only for some HTML tags such as and
:


Will this work in Wicket? Can Wicket recognize this tag as a slot? The answer is yes. Wicket has built-in knowledge of such special tags in HTML. It will internally treat them as complete XML elements.

Displaying the result page The next step is to display the result page. Let's call it ResultPage. Create ResultPage.html and ResultPage.java in the same package. ResultPage.html is: The stock value is: 100.

ResultPage.java is: You need to pass the stock value to the constructor.

public class ResultPage extends WebPage { public ResultPage(int stockValue) { add(new Label("v", Integer.toString(stockValue))); } }

Convert the stock value to a String as the Label component needs a String.

Now, to display this page during the processing of the form submission, modify QuoteInputPage.java:

58

Chapter 2 Using Forms

public class QuoteInputPage extends WebPage { private Model s = new Model("MSFT");

Create the ResultPage

instance. public QuoteInputPage() { For simplicity, use the hash Form form = new Form("f") { code of the stock symbol as @Override the stock value. protected void onSubmit() { String symbol = s.getObject(); ResultPage resultPage = new ResultPage(s.hashCode()); setResponsePage(resultPage); } Tell Wicket to render this page as the }; response. add(form); TextField sym = new TextField("sym", s); form.add(sym); }

}

Now, run the application again. Enter a symbol, click OK and it should display the result page:

Using a combo box to present the stock symbol Currently, you're presenting the stock symbol (business data) contained in the model for the user to edit as an HTML element (UI presentation), with the TextField component doing the translation in the middle: HTML TextField Component



Model

"IBM"

With this separation, it is possible to display the same model as something other than an such as an selected option (

Recommend Documents

Enjoying Web Development with Wicket
Third, it comes with powerful components such as calendar, tree and data grid and it allows ...... Is the page instance really loaded from the hard disk?.........388.

web development with java pdf
Page 1 of 1. File: Web development with java pdf. Download now. Click here if your download doesn't start automatically. Page 1 of 1. web development with java pdf. web development with java pdf. Open. Extract. Open with. Sign In. Main menu. Displayi

Web Development with Clojure.pdf
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item. Web ...

Web Designing & Web Development Tutorial Series - Introduction ...
Page 4 of 12. Difference Difference between Static & Dynamic Websites. Pawan Mall's Production. Static Web. Page/Website. Dynamic Web. Page/Website.

web development design foundations with html5 pdf
web development design foundations with html5 pdf. web development design foundations with html5 pdf. Open. Extract. Open with. Sign In. Main menu.