Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Note
titleThis 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.

"Request processing" in this text means actions that take place within HttpServlet#doGet/doPost() or Filter#doFilter() method call.

At the risk of being unoriginal, request processing in general does two things: changes some data which is stored in HttpSession, database or somewhere else; creates some output which is usually HTMLThere 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 in Wicket that does all the job. Classes delegate request processing & classes delegate the work to each other and in . In a very simplified way in may look it goes like this:
Image Removed
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.

Panel
bgColor#FFFFFF
borderStyledashed

Image Added

  1. browser requests a URL
  2. WicketFilter/Servlet receives request from servlet container and creates RequestCycle object
  3. RequestCycle goes through several states, calling at it state certain method in IRequestCycleProcessor
  4. Depending on request parameters IRequestCycleProcessor creates IRequestTarget (in Wicket this process is referred to as "resolving"). At this stage requested URL is translated into IRequestTarget which already contains requested Page/Component or knows how to create it.
  5. IRequestTarget use existing Page or creates a new one, optionally asks Components to execute callbacks (user code which handles link clicks, form submits, etc.), then asks Page and Components to render themselves
  6. Page/Components execute callbacks and render themselves. Callbacks change state and rendering produce markup and write it to HttpResponse. This is the place where most of the user code resides.
  7. servlet container writes output to browser

There are more classes involved in request processing. Some of them are shown in the diagram below. The diagram is followed by short descriptions of each of these classes. Descriptions say what is the purpose of the class, when it is created and how to get its instance.

It's also a good idea to take a look at these classes' javadocs.

Panel
bgColor#FFFFFF
titleRelation between classes involved in request processing
borderStyledashed

Image Added

WicketFilter/Servlet

What for

Creates and initializes application. Asks application to create request, response and request cycle objects. Starts request processing by calling request() method on RequestCycle.

Anchor
WebApplication
WebApplication

WebApplication

What for

Application and WebApplication can be used to set up a lot of different things which in general may be called configuration. Most frequently used probably are:

  • numerous get*Settings() methods which return modifiable object with specific settings. For full list of all possible settings see list of implemented interfaces in the Settings class.
  • mount*() methods which basically make page or resource accessible by specified URL

Application and WebApplication also have some overridable methods:

  • init() and onDestroy() methods. init() method is called once when WicketFilter/Servlet is created; it should be used for any application setup instead of the constructor. onDestroy() method is called once on filter cleanup.
  • numerous new*() methods which create instance of specified class. They include methods for creating RequestCycle, IRequestCycleProcessor, WebSession, ISessionStore, WebRequest, WebResponse (what means that application creates all these classes). You can override any of these methods to make Wicket use you implementation.

Besides that application can be used for storing any user-defined application scope data.

When created AnchorWebApplicationWebApplication 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 implementation. Factory can be specified in WicketFilter/Servlet configuration in the web.xml using applicationFactoryClassName parameter like this:

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

You can implement IWebApplicationFactory and which will create the application instance you want . But but usually it is not necessary since if . If there is no applicationFactoryClassName parameter in the web.xml, Wicket uses default factory implementation . Default factory which reads applicationClassName parameter and creates application instance of the specified class using reflection.

How to get

There is only one instance of Application per WicketFilter/Servlet. You can get this instance by calling static Application#get() method.

Anchor
RequestCycle
RequestCycle

RequestCycle

What for

The main responsibility of RequestCycle is instructing IRequestCycleProcessor which steps of request handling to execute. For more information see Request cycle and request cycle processor.

When created

New instance of RequestCycle is 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 createdit happens:

Code Block
java
java

class WicketServlet ...

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(); // <--- request processing starts
  ...
}

How to get

Call RequestCycle.get().

Anchor
IRequestCycleProcessor
IRequestCycleProcessor

IRequestCycleProcessor

What for

IRequestCycleProcessor gets instructions from RequestCycle and depending on it:

  • resolves (creates) IRequestTarget. At this step IRequestCycleProcessor finds out which Page/Component was requested and creates IRequestTarget which knows about it. In case of requesting stateful previously accessed page IRequestCycleProcessor asks WebSession to get this page instance.
  • asks IRequestTarget to process events
  • asks IRequestTarget to create response

For more information see Request cycle and request cycle processor.

When created

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().

How to get

Use WebApplication#getRequestCycleProcessor() method (you shouldn't need to do it).

Anchor
IRequestCodingStrategy
IRequestCodingStrategy

IRequestCodingStrategy

What for

In short IRequestCodingStrategy is responsible for converting URL to object representation and vice versa. It "decodes" incoming request and creates a RequestParameters object which is then passed to IRequestCycleProcessor to resolve target. IRequestCodingStrategy also has in some sense reverse method which "encodes" request targets, what means creating a URL for specified IRequestTarget.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):

Code Block
java
java

final WebRequestCycle webRequestCycle = (WebRequestCycle) RequestCycle.get(
public interface IRequestCodingStrategy ...
    RequestParameters decode(Request request);
    CharSequence encode(RequestCycle requestCycle,  webRequestCycle.getWebRequest().getHttpServletRequest();
        webRequestCycle.getWebResponse().getHttpServletResponse();
IRequestTarget requestTarget);

See also Request coding strategy page.

When created

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

How to get

Get IRequestCycleProcessor instance and use IRequestCycleProcessor#getRequestCodingStrategy() method.

Anchor
IRequestTarget
IRequestTarget

IRequestTarget

What for

IRequestTarget contains Page/Component or knows how to create it. It is responsible for calling event handling code (like Form#onSubmit() method) and asking pages and components to render.

When created

IRequestTarget is created by IRequestCycleProcessor on every request and stored in RequestCycle. Which subclass of IRequestTarget will be created depends on RequestParameters instance which is decoded from requested URL. For example if a bookmarkable page is requested, BookmarkablePageRequestTarget is created; if a link is pressed, ListenerInterfaceRequestTarget is created.

See also Request targets page.

How to get

You can get current request target from by getting RequestCycle instance and calling RequestCycle#getRequestTarget() method.

Anchor

WebRequest, WebResponse

What for

Basically WebRequest and wrap HttpServletRequest and HttpServletResponse classes. WebResponse is also used in components as an output for markup.

When created

They are created on every request by Application just before creating RequestCycle. See description for RequestCycle.

How to get

Get RequestCycle instance, use RequestCycle#getRequest/Response() method and cast returned object if exactly WebRequest/Response is needed.

Anchor
WebSession
WebSession

WebSession

What for AnchorWebSessionWebSession

WebSession holds information about a user session including some fixed number of most recent pages. WebSession roughly corresponds to HttpSession.

When created

It is lazily created during request handling. Then it WebSession is stored in HttpSession and restored from there on next request. If HttpSession expires and WebSession in which is stored in it can't be reached anymore new WebSession instance is created.
To customize Session creation you can override Application#newSession() method.

How to get

You can get instance of Session using static Session#get() method.

Anchor
IRequestCycleProcessorIRequestCycleProcessor
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().

...


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

ISessionStore

What for

"The actual store that is used by Session to store its attributes". It means that Session doesn't necessarily store data in HttpSession.

When created

There is one instance of ISessionStore which is created at Application creation.

How to get

Use Application#getSessionStore() method (you shouldn't need to do it).

Anchor

Page, Component

What for

Pages and Components are perhaps the most important part of all. It is the place where most of the user code resides. You should be able to do most of the things you may want to do in web-application without knowing anything else apart from Pages and Components (and perhaps a little bit about Application).

Components generally do three things:
have state, which is state that components in rich GUI application may have. Wicket automatically stores into Session all visited Pages and therefore all nested Components and their state.
provide callbacks, which are basically any user-specified code
render themselves, what means writing some tags to WebResponse. See also Render strategies.

See also Component hierarchy.

When created

Components are created "manually". Usually it happens in a page constructor.
Pages are created:
every time when bookmarkable page is requested. This includes application home page which must be bookmarkable. Bookmarkable pages are created by implementation of IPageFactory (see ISessionSettings#get/setPageFactory() method). See also Bookmarkable pages and links, Pages.
whenever page is explicitly created as a normal java object.

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().

AnchorIRequestTargetIRequestTarget 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:
Image Removed