Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Apache Wicket 8 Is Out!

DZone's Guide to

Apache Wicket 8 Is Out!

Wicket 8 is out and it brings with it the long-awaited support for Java 8.

· Open Source Zone ·
Free Resource

Sensu is an open source monitoring event pipeline. Try it today.

The new main release of Wicket is finally out and it brings with it the long-awaited support for Java 8. Born in 2004 and an Apache top project since 2007, Wicket is still widely used in many different business sectors like e-commerce, financial institutions, educational institutions, non-profit organizations, etc...

If you are new to Wicket and want an overview of his history and features you might find useful this presentation.

In this article, we will take a look at the main new features and improvements that Wicket 8 brings to the table.

Using the New Release

With Maven just add the following dependency:

<dependency>
    <groupId>org.apache.wicket</groupId>
    <artifactId>wicket-core</artifactId>
    <version>8.0.0</version>
</dependency>


Lambda as Model

With Wicket 8 the interface IModel has been made functional. This is probably the most outstanding improvement based on lambda expressions. IMode now comes with a default implementation of every method, with the sole exception of getObject. This means that now IModel represents a read-only model and can be built with a lambda expression:

//build a model returning the current timestamp

IModel<LocalDate> timestamp = () -> LocalDate.now();

The lambda expression must be a supplier.

LambdaModel

PropertyModel uses textual expressions to resolve object properties. That’s nice, but it comes with some drawbacks. For example, the expression cannot be checked at compile time and is not refactoring-friendly. To overcome these problems with Wicket 8 a new kind of lambda-based model has been introduced: org.apache.wicket.model.LambdaModel. This model uses lambda expressions to get/set model object.

In the following code we use method references to operate on a specific object property:

Person person = new Person();

IModel<String> personNameModel = new LambdaModel<>(person::getName, person::setName);

The lambda expression for the getter must be a supplier while the setter requires a consumer.

Lambda and Resources

Since IResource is a single method interface, a resource can also be now implemented with a simple lambda expression that consumes an IResource.Attributes parameter:

IResource helloWorldRes = (attributes) -> attributes.getResponse().write("Hello world!");

Lambda expressions come in handy also with ResourceReference factory methods that accept a resource supplier as an argument. Let’s say we want to mount the resource of the previous example. Using lambdas the code looks like this:

@Override
public void init()
{
  super.init();

  IResource helloWorldRes = (attributes) ->  attributes.getResponse().write("Hello world!");

  ResourceReference resRef = ResourceReference.of("helloworld", () -> helloWorldRes);

  mountResource("/helloworld", resRef);
}

As the first argument for factory methods, we can specify the name of the resource reference or a key for it (an instance of ResourceReference.Key).

Wicket and Microservices

The direct consequence of the improvements done for resources is that Wicket can now be used to easily build microservices, as we do with frameworks like Vert.x or Spark.

public class MyApplication extends WebApplication
{

   @Override
   protected void init()
   {        
    LambdaRestMounter restMounter = new LambdaRestMounter(this);

    Map<String, Object> map = new HashMap<>();

    map.put("integer", 123);
    map.put("string", "message");

    //return plain string
    restMounter.get("/testget", (attributes) -> "hello!", Object::toString);
    //specify a function to transform the returned object into text (json in this case)
    restMounter.post("/testjson", (attributes) -> map, JSONObject::valueToString);
   }
}

See this previous article for a quick introduction to this feature.

Lambda and AJAX Behaviors

Ajax behaviors classes now come with lambda-based factory methods which make their creation easier and less verbose. For example AjaxEventBehavior can be instantiated like this:

AjaxEventBehavior.onEvent("click", ajaxtarget -> //some lambda stuff)

In the following table are listed these factory methods along with their behavior classes:

Class Name

Method Name

AbstractAjaxTimerBehavior

onTimer

AjaxEventBehavior

onEvent

AjaxNewWindowNotifyingBehavior

onNewWindow

AjaxSelfUpdatingTimerBehavior

onSelfUpdate

AjaxFormChoiceComponentUpdatingBehavior

onUpdateChoice

AjaxFormComponentUpdatingBehavior

onUpdate

AjaxFormSubmitBehavior

onSubmit

OnChangeAjaxBehavior

onChange


Navigate Children Components With Streams

With Wicket 8 we can iterate through children component harnessing Java 8 streams. Class Markup container comes with methods stream(), which returns just the direct children, and streamChildren() which returns all children.

parent.streamChildren().filter(component -> component instanceof FormComponent);


More Info and Contacts

To discover more new features of Wicket 8 and see more examples don't forget to visit our official site and follow us on Twitter.

From bare metal to Kubernetes, Sensu gives you complete visibility across every system and protocol. Get started today.

Topics:
java ,web fragmentation ,lambda expression ,microservices ,apache ,wicket

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}