The girls and guys of 42 Lines have released a set of plugins that enable you to open a specific Wicket component in your Eclipse workspace when looking at it in Firefox. This will save so many hours looking up components in your web page and source code, that it will probably save lives.
And George Armhold has ported the plugin to IntelliJ’s IDEA. Who is going to build this for Netbeans?
In the previous article I described how to mount pages at nice looking urls. Today I’ll show you how to mount resource.
Recently there were several people asking in the mailing lists how to serve images loaded from a database so this will be the functionality of the demo application for this article.
To mount a resource you should do:
MyApp.java
public void init() { super.init(); mountResource("/mount/path", new SomeResourceReference()); // #mountResource() is a shortcut for: // mount(new ResourceMapper("/mount/path", new com.example.SomeResourceReference())); } |
With this setup requests to http://host/mount/path will be handled by com.example.SomeResourceReference. The extraction of the request parameters is the same as with pages. A request to http://host/mount/path/indexed?queryNamed=queryValue will have one indexed and one named parameters. They can be read with Attributes.getParameters().get(0) and .get(“queryNamed”) respectfully. Named indexed parameters also work the same way as with pages.
Now since we know how to mount resources let’s see how to create links to them.
MyApp.java
public void init() { super.init(); mountResource("/images/${name}", new ImageResourceReference()); mountPage("imagesPage", ImageResourcesPage.class); } |
Here we mounted the resource reference that will find the images and a page which will make use of them.
The important thing when creating the resource reference is to give it unique ResourceReference.Key and provide implementation of #getResource() method:
ImageResourceReference.java
public ImageResourceReference() { // this creates a Key with scope 'ImageResourceReference.class' // and a name 'imagesDemo' super(ImageResourceReference.class, "imagesDemo"); } @Override public IResource getResource() { return new ImageResource(); } |
The key is needed by ResourceMapper to be able to recognize the resource reference when asked to create urls to it.
ImageResource is an implementation of IResource which will serve the images.
ImageResource.java:
private static class ImageResource extends DynamicImageResource { @Override protected byte[] getImageData(Attributes attributes) { PageParameters parameters = attributes.getParameters(); StringValue name = parameters.get("name"); byte[] imageBytes = null; if (name.isEmpty() == false) { imageBytes = getImageAsBytes(name.toString()); } return imageBytes; } private byte[] getImageAsBytes(String label) {...} @Override public boolean equals(Object that) { return that instanceof ImageResource; } } |
Since we need to serve images we take advantage of Wicket’s DynamicImageResource which cares about HTTP headers and stuff and leave us only to load the image’s bytes. The parameter Attributes gives us access to the current request, response and the extracted request parameters. The override of #equals() is the second requirement needed by ResourceMapper to fully recognize the mapped resource. For our need any ImageResource instance will do the job.
To create urls to images you should use the following code:
ImageResourcesPage.java
ResourceReference imagesResourceReference = new ImageResourceReference(); PageParameters imageParameters = new PageParameters(); String imageName = "anyName.jpg"; imageParameters.set("name", imageName); CharSequence urlForImage = getRequestCycle().urlFor(imagesResourceReference, imageParameters); ExternalLink link = new ExternalLink("link", urlForImage.toString()); |
The link will produce urls like /images/anyName.jpg.
With this the task is done.
The full source of the demo application can be found in my Github account.
In the previous article I described how IRequestMappers work. In this installment I’ll show you how to mount pages at nice looking urls.
In Wicket 1.4 there were several implementations of IRequestTargetUrlCodingStrategy with which the developer was able to mount a page at a given path and the request parameters were encoded/decoded depending on the chosen coding strategy. E.g. with QueryStringUrlCodingStrategy the parameters were read/written in the request’s query string – /mount/path?param1=value1¶m2=value2, with IndexedParamUrlCodingStrategy the parameters are represented as part of the request path – /mount/path/param1/param2, with MixedParamUrlCodingStrategy it was possible to use both query string based and indexed based ones.
In Wicket 1.5 all these are combined in MountedMapper. It can encode/decode the parameters in the query string, as indexed and as named indexed.
To mount a page with MountedMapper you should do something like:
MyApp.java
public void init() { super.init(); mountPage("/mount/path", MyPage.class); // #mountPage() is a shortcut for: // mount(new MountedMapper("/mount/path", MyPage.class)); } |
Now a request to http://host/mount/path will be handled by MyPage and it wont have any parameters. A request to http://host/mount/path/indexed?queryNamed=queryValue will have one indexed and one named parameters. They can be read with PageParameters#get(0) and #get(“queryNamed”) respectfully.
The new functionality in 1.5 is that now you can have indexed parameters which have names.
If you use mountPage(“/mount/path/${named1}/${named2}”, MyPage.class); then the request url may look like http://host/mount/path/value1/value2 and the parameters’ values can be read with PageParameters#get(“named1″) and #get(“named2″). MyPage will handle this request only if both parameters are provided. If ‘named2′ is not provided then the request mapper wont match and will let another mapper to handle the request.
One more cool thing is that you can have optional indexed named parameters. The difference with mandatory ones is that they use hash sign instead of dollar sign – #{optional}. A mapping like mountPage(“/mount/path/${named1}/#{named2}”, MyPage.class); will match for both requests http://host/mount/path/value1 and http://host/mount/path/value1/value2.
To mount all pages in a package now you should use:
MyApp.java
1 2 3 4 | public void init() { super.init(); mountPackage("package", com.example.pages.SomePage.class); } |
With this a request to http://host/package/AnotherPage will be handled by AnotherPage only if it is in the same package as SomePage, i.e. com.example.pages.
The last mapper which we will discuss today is BookmarkableMapper. This is the mapper which is used when there is no explicit mapping for a page. For example using setResponsePage(com.example.pages.NotMappedPage.class) will produce an url like http://host/wicket/bookmarkable/com.example.pages.NotMappedPage. This functionality is the same as ?wicket:bookmarkable=com.example.pages.NotMappedPage in Wicket 1.4. To change the namespace – wicket/bookmarkable – you’ll have to setup custom IMapperContext by overriding Application.newMapperContext().
For more information about other mappers provided by Wicket read Request Mappers wiki page.
Some code exploring this topic can be found at: Mappers examples.
In the next article I’ll show you how to mount resources.
Hi, in series of short articles I’ll try to explain the new stuff in Wicket 1.5. It may be a completely new feature or a change since 1.4, hopefully for good.
In this first article I’ll talk about the new request mappers. They are semi- new feature, semi-change because they completely replace the functionality that IRequestTargetUrlCodingStrategy provided in 1.4.
Simply said, the Application class has a set of IRequestMapper‘s and for each request the RequestCycle asks these mappers whether any of them knows how to handle the current request’s url.
Wicket pre-configures several mappers [1] which are used for the basic application functionality like a mapper for the home page, a mapper for Wicket resources, for bookmarkable pages, etc. The user application can add additional mappers with the various WebApplication#mountXYZ() methods.
The mapper has two main tasks:
In the next article I will show how to use most of the default mapper implementations.
1. See the source of SystemMapper for more details.
2. IRequestHandler is what IRequestTarget is in Wicket 1.4.
Eclipse users have been at a disadvantage for Apache Wicket development when compared to Netbeans or IntelliJ IDEA users. For those IDEs some nice integration plugins exist for web development using Wicket.
I just discovered QWickie, a plugin for Eclipse, which has the following features:
Be aware that this plugin is still 0.0.4, so use at your own risk!
Taken from the Wicket mailing list:
> Hey folks, The Basement Coders will be at JavaOne and doing
> a podcast right from the Mason street tent Tuesday at
> 10am! We would love to meet some Wicket peeps
> throughout the week!
Fellow Apache Wicket committer and TDD enthousiast Timo Rantalaiho discusses how he came to Apache in this Apache 10th anniversary video:
Take a look at his shirt :)
Peter Thomas, renowned for his previous comparisons between web frameworks has put all the popular choices of the moment next to one another in one short article. I haven’t tried the benchmark myself, but I like the results:
Overall, Wicket is fastest, with Tapestry coming a close second.
Read it yourself, and then confirm the results yourself.
The Apache Wicket project is proud to announce the release of Apache Wicket 1.4. Apache Wicket is an open source, component oriented Java web application framework. With overwhelming support from the user community, this release marks a departure from the past where we leave Java 1.4 behind and we require Java 5 as the minimum JDK version. By moving to Java 5 as the required minimum platform, we were able to utilize Java 5 idioms and increase the type safety of our APIs. Using Java generics you can now write typesafe web applications and create typesafe, self documenting, reusable custom components.
You can download the release here: http://www.apache.org/dyn/closer.cgi/wicket/1.4.0
Or use this in your Maven pom’s to upgrade to the new version:
<dependency> <groupid>org.apache.wicket</groupid> <artifactid>wicket</artifactid> <version>1.4.0</version> </dependency> |
You will need to upgrade all modules (i.e. wicket, wicket-extensions) to their 1.4 counterparts. It is not possible to mix Wicket 1.3 libraries with 1.4 libraries due to API changes.
From all the changes that went into this release, the following are the most important ones:
Apart from these changes, the release is mostly compatible with Wicket 1.3 and upgrading shouldn’t take too long. Early adopters report about a days work to upgrade medium to large applications to Wicket 1.4. Read the migration guide to learn more about the changes in our APIs. To learn more about all the improvements and new features that went into this release, check the solved issue list in our JIRA instance.
Read the rest of this entry »
The Apache Wicket team is proud to present the release of Apache Wicket 1.3.7. This will be the last feature release for the 1.3.x branch. Going forward, only security fixes will be released in the 1.3.x branch – meaning that 1.3.7 may be the last release in this branch. All users are encouraged to upgrade to 1.4.0 as soon as possible. As work begins on 1.5 in the near future, we will be supporting 1.4.x and 1.5.x.
Eager people click here to download the distribution, others can read the release notes. We thank you for your patience and support.
The Wicket Team
With this book, Wicket will become the greatest territory the Dutch have settled since Manhattan.
Nathan Hamblen
Senior Software Engineer, Teachscape Inc.
This is the complete and authoritative guide to Wicket, written and reviewed by the core members of the Apache Wicket team. If there's anything you want to know about Wicket, you are sure to find it in this book.
Jonathan Locke
Founder and Architect of Apache Wicket, Foreword Wicket in Action
Without question, Wicket in Action... is the be-all and end-all when it comes to Wicket.
Geertjan Wielenga, Wicket Netbeans Plugin Author
The tutorial and conversational tone of the writing makes the book very approachable.
Nick Heudecker
System Mobile
Loved the sample application—it tied everything together.
Phil Hanna
Senior Software Developer, SAS Institute
The essential guide for learning and using Wicket.
Erik van Oosten
Lead programmer and Project Manager, JTeam
Finally, the Web Framework of web frameworks, Apache Wicket, now has a bible of its own.
Per Ejeklint
Senior Software Architect, Heimore group
Wicket is an innovative evolution of the MVC programming with simple roots, but without a primer such as this, it can be more challenging than it needs to be.
Brian Topping
Founder, Bill2 Inc.
Wicket In Action glues the areas of web development with Apache Wicket together and gives a great overview of Apache Wicket...it will make a great compendium.
Nino Martinez Wael
Java Specialist, Jayway Denmark