You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

This is not exactly how Wicket 1.3 works

Some of the things are grossly simplified. See source code and javadocs to find out how Wicket really works.

There are a number of classes involved in request processing. The most important ones are: #WebApplication, #WebRequest, #WebResponse, #WebSession, #RequestCycle, #IRequestCycleProcessor, #IRequestCodingStrategy and #IRequestTarget. These is no single class that does all the job. Classes delegate request processing to each other and in a very simplified way in may look like this:

Here request processing starts with WicketFilter/Servlet being called by servlet container and "ends" with IRequestTarget which asks page to render and/or calls event handling code.


WebApplication contains some classes (such as IRequestCycleProcessor) essential for request processing. It is also used for storing application scope data such as Settings and SharedResources.
WebApplication is created when WicketFilter/Servlet is initialized. It is created by IWebApplicationFactory which can be specified in the web.xml using applicationFactoryClassName parameter:

<init-param>
	<param-name>applicationFactoryClassName</param-name>
	<param-value>org.apache.wicket.MyApplicationFactory</param-value>
</init-param>

You can implement IWebApplicationFactory and create the application instance you want. But usually it is not necessary since if there is no applicationFactoryClassName parameter in the web.xml Wicket uses default factory implementation. Default factory reads applicationClassName parameter and creates application instance of specified class using reflection.
There is only one instance of Application per WicketFilter/Servlet. You can get this instance by calling Application#get() method.


RequestCycle does some general request processing and delegates most of it to IRequestCycleProcessor (see RequestCycle#step()). RequestCycle also contains instances of WebRequest, WebResponse which basically wraps HttpServletRequest and HttpServletResponse adding Wicket related functionality. Instances of these classes are created on every request.
This is a pseudo code of how RequestCycle is created:

public final void doGet(final HttpServletRequest servletRequest,
                        final HttpServletResponse servletResponse)
{
  ...
  // WebApplication instance is already created while initializing servlet/filter
  final WebRequest request = webApplication.newWebRequest(servletRequest);
  final WebResponse response = webApplication.newWebResponse(servletResponse);
  RequestCycle cycle = webApplication.newRequestCycle(request, response);
  cycle.request();
  ...
}

You can customize creation of WebRequest, WebResponse and RequestCycle by overriding WebApplication#newWebRequest(), newWebResponse() or newRequestCycle().
To obtain RequestCycle instance you can call RequestCycle#get() which gets instance from ThreadLocal variable. You can get obtain WebRequest, WebResponse instances from WebRequestCycle calling getWebRequest(), getWebResponse() methods. To get HttpServletRequest/Response you can do something like this (this is not straightforward but you should not need to do it in Wicket):

final WebRequestCycle webRequestCycle = (WebRequestCycle) RequestCycle.get();
        webRequestCycle.getWebRequest().getHttpServletRequest();
        webRequestCycle.getWebResponse().getHttpServletResponse();


WebSession holds information about a user session including some fixed number of most recent pages. WebSession roughly corresponds to HttpSession. It is lazily created during request handling. Then it is stored in HttpSession and restored from there on next request. If HttpSession expires and WebSession which is stored in it can't be reached anymore new WebSession instance is created.
To customize Session creation you can override Application#newSession().
You can get instance of Session using Session#get() method.


IRequestCycleProcessor is responsible for handling the steps of a request cycle. Its methods are called in a pre-defined order:

  • IRequestTarget resolve(RequestCycle, RequestParameters) is called to get the request target. A request might refer to e.g. a bookmarkable page, a component on a previously rendered page. RequestParameters here consists of possible optional parameters that can be translated from servlet request parameters and serves as a strongly typed variant of these (see IRequestCodingStrategy).
  • void processEvents(RequestCycle) is called after the target is resolved. It is meant to handle events like calls on components e.g. onClick(), onSubmit() event handlers.
  • void respond(RequestCycle) is called to create a response to the requesting client i.e. generate web page or do redirect.
    Typically IRequestCycleProcessor resolves target and then delegates event processing and response generation to this target.

There is one instance of IRequestCycleProcessor per Application. It is lazily created during the first request. Its creation can be customized by overriding WebApplication#newRequestCycleProcessor().


IRequestCodingStrategy implementations are responsible for digesting the incoming request and creating a suitable RequestParameters object for it, as well as creating URL representations for request targets. These are methods that do it:

RequestParameters decode(Request request);
CharSequence encode(RequestCycle requestCycle, IRequestTarget requestTarget);

There is one instance of IRequestCodingStrategy per IRequestCycleProcessor. It is usually WebRequestCodingStrategy which is lazily created during the first request. Its creation can be customized by overriding AbstractRequestCycleProcessor#newRequestCodingStrategy().


There are different subclasses of IRequestTarget for different types of requests. For instance if a bookmarkable page is requested BookmarkablePageRequestTarget will be used, if a link is pressed on a rendered page ListenerInterfaceRequestTarget will be used. These targets will actually ask the page to render or call event handling code (for instance onSubmit() method).
Instance of IRequestTarget is created on every request by the request cycle processor.
You can get current request target by calling RequestCycle#getRequestTarget().

On the whole request processing looks roughly like this:

  • No labels