| |
| |
| |
| Class _org.apache.wicket.request.cycle.RequestCycle_ is the entity in charge of serving a web request. Our application class creates a new _RequestCycle_ on every request with its method _createRequestCycle(request, response)_. |
| |
| Method _createRequestCycle_ is declared as final, so we can't override it to return a custom subclass of _RequestCycle_. Instead, we must build a request cycle provider implementing interface _org.apache.wicket.IRequestCycleProvider_, and then we must tell our application class to use it via the _setRequestCycleProvider_ method. |
| |
| The current running request cycle can be retrieved at any time by calling its static method _RequestCycle.get()_. Strictly speaking this method returns the request cycle associated with the current (or local) thread, which is the thread that is serving the current request. A similar _get()_ method is also implemented in classes _org.apache.wicket.Application_ (as we have seen in <<_configuration_of_wicket_applications,paragraph 4.2.2>>) and _org.apache.wicket.Session_ in order to get the application and the session in use by the current thread. |
| |
| NOTE: The implementation of the get method takes advantage of the standard class _java.lang.ThreadLocal_. See its JavaDoc for an introduction to local-thread variables. |
| |
| Class _org.apache.wicket.Component_ provides the _getRequestCycle()_ method which is a convenience method that internally invokes _RequestCycle.get()_: |
| |
| [source,java] |
| ---- |
| public final RequestCycle getRequestCycle() { |
| return RequestCycle.get(); |
| } |
| ---- |
| |
| === RequestCycle and request processing |
| |
| NOTE: This paragraph will provide just the basic informations about what happens behind the scenes of request processing. When you work with Wicket it's unlikely to have a need for customizing this process, so we won't cover this topic in detail. |
| |
| In order to process a request, _RequestCycle_ delegates the task to another entity which implements interface _org.apache.wicket.request.IRequestHandler_. There are different implementations of this interface, each suited for a particular type of requested resource (a page to render, an AJAX request, an URL to an external page, etc.). |
| |
| To resolve the right handler for a given HTTP request, the _RequestCycle_ uses a set of objects implementing the _org.apache.wicket.request.IRequestMapper_ interface. The mapping interface defines the _getCompatibilityScore(Request request)_ method which returns a score indicating how compatible the request mapper is for the current request. _RequestCycle_ will choose the mapper with the highest score and it will call its _mapRequest(Request request)_ method to get the proper handler for the given request. Once _RequestCycle_ has resolved a request handler, it invokes its method _respond(IRequestCycle requestCycle)_ to start request processing. |
| |
| The following sequence diagram recaps how a request handler is resolved by the _RequestCycle_: |
| |
| image::../img/request-cycle-handler.png[] |
| |
| Developers can create additional implementations of _IRequestMapper_ and add them to their application via the _mount(IRequestMapper mapper)_ method of the _WebApplication_ class. In paragraph 10.6 we will see how Wicket uses this method to add built-in mappers for mounted pages. |
| |
| === Generating URL with the urlFor and mapUrlFor methods |
| |
| The _RequestCycle_ is also responsible for generating the URL value (as _CharSequence_) for the following entities: |
| |
| * a page class, via the _urlFor(Class<C> pageClass, PageParameters parameters)_ method |
| * an _IRequestHandler_ via the _urlFor(IRequestHandler handler)_ method |
| * a _ResourceReference_ via the _urlFor(ResourceReference reference, PageParameters params)_ method (resource entities will be introduced in |
| <<_resource_management_with_wicket,chapter 19>>). |
| |
| The overloaded _urlFor_ method from above also has a corresponding version that returns an instance of _org.apache.wicket.request.Url_ instead of a _CharSequence_. This version has the prefix 'map' in its name (i.e. it has _mapUrlFor_ as full name). |
| |
| === Method setResponsePage |
| |
| The _RequestCycle_ class contains the implementation of the _setResponsePage_ method we use to redirect a user to a specific page (see <<_wicket_links,paragraph 4.4>>). The namesake method of class _org.apache.wicket.Component_ is just a convenience method that internally invokes the actual implementation on current request cycle: |
| |
| [source,java] |
| ---- |
| public final void setResponsePage(final Page page) { |
| getRequestCycle().setResponsePage(page); |
| } |
| ---- |
| |
| === RequestCycle's hook methods and listeners |
| |
| The _RequestCycle_ comes with some hook methods which can be overridden to perform custom actions when request handling reaches a specific stage. These methods are: |
| |
| * *onBeginRequest():* called when the RequestCycle is about to start handling the request. |
| * *onEndRequest():* called when the RequestCycle has finished to handle the request |
| * *onDetach():* called after the request handling has completed and the RequestCycle is about to be detached from its thread. The default implementation of this method invokes detach() on the current session (the Session class will be shortly discussed in paragraph 9.4). |
| |
| Methods onBeforeRequest and onEndRequest can be used if we need to execute custom actions before and after business code is executed, such as opening a Hibernate/JPA session and closing it when code has terminated. |
| |
| A more flexible way to interact with the request processing is to use the listener interface _org.apache.wicket.request.cycle.IRequestCycleListener_. In addition to the three methods already seen for RequestCycle, this interface offers further hooks into request processing: |
| |
| * *onBeginRequest(RequestCycle cycle):* (see the description above) |
| * *onEndRequest(RequestCycle cycle):* (see the description above) |
| * *onDetach(RequestCycle cycle):* (see the description above) |
| * *onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler):* called when an IRequestHandler has been resolved. |
| * *onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler):* called when an IRequestHandler has been scheduled for execution. |
| * *onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler):* called when an IRequestHandler has been executed. |
| * *onException(RequestCycle cycle, Exception ex):* called when an exception has been thrown during request processing. |
| * *onExceptionRequestHandlerResolved(RequestCycle rc, IRequestHandler rh, Exception ex):* called when an IRequestHandler has been resolved and will be used to handle an exception. |
| * *onUrlMapped(RequestCycle cycle, IRequestHandler handler, Url url):* called when an URL has been generated for an IRequestHandler object. |
| |
| To use the request cycle listeners we must add them to our application which in turn will pass them to the new _RequestCycle_'s instances created with _createRequestCycle_ method: |
| |
| [source,java] |
| ---- |
| @Override |
| public void init() { |
| |
| super.init(); |
| |
| IRequestCycleListener myListener; |
| //listener initialization... |
| getRequestCycleListeners().add(myListener) |
| } |
| ---- |
| |
| The _getRequestCycleListeners_ method returns an instance of class _org.apache.wicket.request.cycle.RequestCycleListenerCollection_. This class is a sort of typed collection for _IRequestCycleListener_ and it also implements the http://en.wikipedia.org/wiki/Composite_pattern[Composite pattern] . |