Enjoying Web Development with Wicket - Google Sites

2 downloads 132 Views 2MB Size Report
application for their organization using Wicket, Spring and Hibernate. ...... pom.xml file in the project root folder (c
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 >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. xmlns:wicket= "http://wicket.apache.org/dtds.>world
Use the "wicket" prefix to indicate that this slotid attribute belongs to the http://wicket.apache.org/dtds. xmlns:wicket="http://wicket.apache.org/dtds.>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 (): 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

Suggest Documents