In my case images are stored in JCR but this could be any other repository like db or file system where arbitrary images could be added or removed over time.
I also want that images have stable (bookmarkable) URLs, which makes them suitable for indexing by web crawlers and caching by web browsers.
I first checked the wicket "bible" Wicket in Action but this use case is not treated there.
Finally it turned out wicket does provide a way to do it in simple Java - shared resource with parameters.
Define a class to serve images
Create a class e.g. Images extending WebResource. Essentially this class has to implement the method getResourceStream(), which should return an IResourceStream implementation. (IResourceStream provides the actual data stream in terms of InputStream, data size, content type, etc.) The important thing here is that Images class can call inherited method getParameters() to get the query parameters (as ValueMap) from the URL. These parameters can be used to identify the specific image to be streamed. Something like this
String imageId = getParameters().getString("id");
Bind the image serving class
The Images class created above can be bound to a specific URL, so whenever this URL is requested, the bound object is used to stream the response. This is done in the application init() method.
getSharedResources().add("images", new Images());This would produce image URLs like resources/org.apache.wicket.Application/images. To shorten the URLs to resources/global/images, add this again in init() method
Display an image
Finally, use this to put an image on a page
new Image("image", new ResourceReference("images"),
new ValueMap("id=" + imageId))
This will result in image URL like resources/global/images?id=image105
Of course this mechanism could be used for any kind of resource (e.g. PDF documents). It is only a matter of Content-Type.