Skip to content

Instantly share code, notes, and snippets.

@dashorst
Last active February 15, 2021 06:23
Show Gist options
  • Save dashorst/6308833 to your computer and use it in GitHub Desktop.
Save dashorst/6308833 to your computer and use it in GitHub Desktop.
Apache Wicket is an open source Java component oriented web application framework. This document specifies modernization to the way Wicket handles PageParameters in the processing of requests and the lifecycle of Page components, based on the specifications done for JAX-RS (JSR-311 and JSR-339).
Please see https://github.com/dashorst/wicket-rfcs/blob/master/wicket-rfc-0001.txt for the RFC.
Please comment either inline in the github repository, or reply to the message
thread on the dev@wicket.apache.org mailing list.
@ivaynberg
Copy link

if we were to implement 2.2 (field injection) this would have to be done from the Component's constructor, so we would spread creation and initialization of parameters across two places: component and page factory - this sucks. also, it is rarely these things are useful as fields because we dont usually want them serialized. most of the time we pull a value, wrap it in an LDM and store that as a field.

@ivaynberg
Copy link

2.3 Custom type parameters
it is not enough to simply say you need a constructor that takes a String. we need a converter system. for example, we often pull ids out of PageParameters and load entities. we cannot have entities take a string parameter and then reload itself with data.

whether or not we can/should reuse the existing converter infrastructure we have should also be discussed.

@ivaynberg
Copy link

    // register all pages in the package and its child packages
    mountPackage("com.example.web.pages");

that will basically require a package scan, so not sure why we are still discussing whether or not we need one in 3.3...

@ivaynberg
Copy link

we should keep the existing PageParameters infrastructure unchanged.

  • i do not want to migrate all the pages that use PageParameters when I upgrade
  • in a few instances page parameters are dynamic and i do not want to/cannot list all possible ones in annotations

@ronaldtm
Copy link

What if you have many pages that receive the same parameters, and those have to be converted to a TO? Or multiple-field objects (like, a Date could be created by three inputs, '_year', '_month', and '_day', with some common prefix).

With PageParameters, I could just have a static method that takes PageParameter and returns the object, and reuse it in every page. Not being allowed to do this would take a lot of control off our hands.

And even if this new parameter system implemented something like SpringMVC's annotated parameters (can take POJOs, inject parameters into their properties, etc.), I think it would be very complex and confusing (just like SpringMVC).

@bernard01
Copy link

We need to show how this parameter binding works on the side where the URL is created inside Wicket not just one-way. With the RFC, only the parsing of the parameter on the receiving end is shown. With the RFC we would have to duplicate the rules by which the parameters are bound to URLs on the receiving AND the sending side.

With the existing scheme, we can delegate the creation of a link to a page in code in a typesafe way. Perhaps the RFC can be updated to show how this works with the new scheme.

Currently we can encapsulate this two-way in the page as follows:
MyPage.java

// A static LongParameter object knows how to convert from and to
// The name of the parameter in URL "ssn" is encapsulated in the instance
private static final LongParameter PARAMETER_ID = new LongParameter("ssn");

// Constructor
public MyPage(final PageParameters parameters) {
        Long securityNumber = PARAMETER_SECUTRITY_NUMBER.getValue(parameters);


// parameter interface
public static PageParameters createParameters(final long securityNumber) {
    final PageParameters parameters = new PageParameters();
    PARAMETER_SECUTRITY_NUMBER.addToParameters(parameters, securityNumber);
    return parameters;
}

Other page:

// Delegate the creation of page parameters to destination page
new BookmarkablePageLink("edit", MyPage.class, MyPage.createParameters(securityNumber)

Using annotations for brevity does not necessarily improve code quality if it does not encapsulate the formatting rules for these parameters.

@CedricGatay
Copy link

There is nothing regarding the use of optional parameters. How should we handle this use case, should we use multiple constructors [1] or should we use a @DefaultValue annotation [2] to stay on par with Jax-RS API ?

[1] :

 @Path("/page/{req}/val/{opt}")
 public class MyPage extends WebPage{
    public MyPage(@PathParam("req") String req){
    }

    public MyPage(@PathParam("req") String req, 
                          @PathParam("opt") String opt){
    }
 }

[2] :

 @Path("/page/{req}/val/{opt}")
 public class MyPage extends WebPage{
    public MyPage(@PathParam("req") String req, 
                          @DefaultValue("default") @PathParam("opt") String opt){
    }
 }

@martin-g
Copy link

How many users have complained that the current way (using PageParameters) causes them troubles ?
What kind of troubles ?
Please provide a list of open tickets in JIRA which will be solved with this RFC.

@martin-g
Copy link

7.1.3 setResponsePage(Class<?>, PageParameters) removed

What will be the new way to make a redirect with path and/or query parameters ?

@martin-g
Copy link

org.apache.wicket.request.resource.IResource#respond

At the moment one could have:

  • a stateless resource - the mounted resource reference create a new IResource for each request
  • a stateful resource - the mounted reference reused the same resource

In both cases IResource#respond() receives IResource.Attributes with the current Request, Response and PageParameters.

Do you imagine how the new way will be applied here ?

@bitstorm
Copy link

Hi everybody!

I have to finish yet to read the complete rfc document. I agree that sometimes PageParameters can generate a little bit of confusion when we use them with page constructor or links. I also agree that the code for mounting pages/resources should be more neat and clear (too many IRequestMapper ??).
However I don't understand why we should get rid (or heavily modify) PageParameters. The funny thing (of course for me) is that PageParameters have been very helpful writing REST module for Wicket, which basically offers the same features (and the same approach) of JAX-RS.
REST module for Wicket: https://github.com/wicketstuff/core/tree/master/jdk-1.6-parent/wicketstuff-restannotations-parent

@bernard01
Copy link

I find it very clean and extremely easy to deal with PageParameters. They allow developers to instantiate pages with completely different sets of parameters. To formalise the conversion between PageParameters and sets of values (not just IModel) one can use two-way converters within the target page. That achieves 100% type safety:

setResponsPage(MyPage.class, MyPage.createParameters(parameter1, parameter2)

The proposed solution must show how to achieve type safety.

varargs or builder that add arbitrary parameters cannot be used to provide type safety (which comes with code completion in IDEs). Here is why: Wrap a parameter builder in a type safe converter. The parameter builder or varargs object - what are they? Just another way to represent name value pairs - which is what PageParameters are - except they are broken because the names are missing.

So one cannot build the type safety even with a converter.

The annotation approach is good for web services where the consumer is outside the system, and a complete tool chain exists to generate the annotations and wsdl which provides the type safety at the other end. Do we want to provide this?

Perhaps behind the annotations should be be real classes that provide the type safety . Something like jsr303 bean validation.

This is a generic problem of two-way mapping between name-value pairs and and arbitrary objects. Why is Wicket trying to solve this? Given the maturity of the Java ecosystem and the basic nature of the problem I would guess that either 1) we can use an existing solution and plug it in, or 2) this problem does not have a generic solution.

I guess it is 2) because of validation constraints.

I would prefer if Wicket keeps PageParameters and provides PageParameter converters to support type safety. Developers just code them anyway so we are not asking for them. They would be great for beginners though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment