|
Page Edited :
SLINGxSITE :
Request Processing
Request Processing has been edited by Mike Mueller (Feb 13, 2008). Content:HTTP Request Processing
One of the core problems towards understanding how Sling works is knowing how a Client Request is processed by Sling. This page describes the flow of processing requests inside Sling. Core Request ProcessingThe HTTP request enters Sling in the org.apache.sling.core.ComponentRequestHandlerImpl.service(ServletRequest req, ServletResponse res) method as the ComponentRequestHandlerImpl is registered as the Servlet handling HTTP requests. This method sets up the initial ComponentRequest and ComponentResponse objects and hands the request over to the first ComponentFilterChain. This first filter chain calls all ComponentFilter instances registered as request level filters. After processing all filters in the request level filter chain, the request is handed over to the second ComponentFilterChain which calls all ComponentFilter instances registered as component level filters. At the end of the second filter chain the service method of the actual Component to which the request resolved is called. As the component is now processing the request, it may decide to dispatch the request to some other content such as for example a paragraph system or navigation component. To do this, the component will call the RequestDispatcher.include method. If the request dispatcher dispatches to a Content object Sling will hand the dispatch request over to the component level filter chain, which at the end will call the service method for the Content object to dispatched to. This process may be repeated at the component's discretion only limited by processing resources such as available memory. As can be seen Sling itself is absed on the Component API ComponentFilter mechanism. As such Sling provides and uses the following filters in the Sling Core bundle:
Deducing from these lists of filters, the actual request processing can be refined into the following steps:
The default request level filter chain setup ends with finding the Content object requested by the request URL. After having found this object, the request is handed over to the component level filter chain, which is concerned with handling filtering on a single Content instance. As such, the component level filter chain is used for each Content object which is to be serviced either on behalf of the HTTP request or on behalf of request dispatcher. Thus the component level filter chain will generally called multiple times during a single request.
Again, deducing from the list of filters, the following steps are taking to service a given Content object:
After resolving the Component object default component filter chain terminates and control is handed over to the service method of the Component object resolved in the last step. At the discretion of the component request dispatchers may now be acquired to render other Content objects. In this case the component level filter chain is simply kicked of again resulting in the service method of another Component being called. And so forth. Resolving ContentAs we have seen, the last step in the request level filter chain is the resolution of the request URL into a Content object. The URL Mapper Filter implementing this resolution uses an instance of the org.apache.sling.content.ContentMapper interface which is acquired by calling the org.apache.sling.content.jcr.JcrContentManagerFactory with the repository session acquired by the authentication filter. The URL Mapper filter then tries to apply fixed mappings from request URL to destination paths to support shortcut URLs. For example the root path / may be mapped into the default landing page at /default/home. The list of such mappings is configurable through the Configuration Admin Service. Next the URL Mapper tries to apply prefix matching patterns. A list of patterns is iterated checking whether the prefix applies and, if so, replacing the prefix with another prefix and trying to resolve the result. This functionality enables relocation of a subtree of the repository. For example, all requests whose prefix is /here might be remapped with the new prefix /content/there. The result of this remapping is then resolved. Resolution (currently) takes place on the last path segment of the request URL containing at least one dot. Parts of that segment are cut off after dots until no more dots exist in the URL. For each resulting substring, the ContentManager.load(String) method is called. This processing terminates if a Content object is found or if there is nothing to cut off any more. This resolution is very simple and straight forwards. Future development may add support for the following features:
Registering ComponentsThe last step of the component level filter chain is resolving the Component from the component ID of the Content object. Sling implements this resolution by making use of the OSGi service registry. That is, each component is to be registered as a service with the name org.apache.sling.component.Component. The ComponentResolverFilter is listening for these components and registers them internally in a map indexed by the IDs of the component as returned by the Component.getId() method. When a component has to be resolved, the component ID returned by the Content object is simply looked up in the component map. If found, that component is used. Otherwise a fall back algorithm is applied which is described on the Default Content Mapping and Request Rendering page. Reqistering FiltersJust as Component instances used by Sling are expected to be registered as OSGi services, the {{ComponentFilter}}s to be Service properties set upon registration of the filter define the chain to which the filter belongs and the order in which the filters should be processed:
Content is a Java ObjectIt is crucial to understand that Content is an interface and the request processor of Sling does not actually care, how the Content instance comes to live as long as the is such an object and there is a Component instance capable of servicing the Content object. By default Sling uses the URL Mapper to resolve the request URL into a Content object. When a Component is tasked with servicing a Content object it usually uses the ComponentRequestDispatcher to ask Sling to service another content object generally identified by a (relative or absolute) path to a JCR Repository Node from which the Content object is loaded. But instead of having Sling resolve a path into a Content object the component may just as well create a Content object and hand it over to the ComponentRequestDispatcher for service. Consider a request which is handled by a PageComponent. This component has to draw a navigation tree somewhere in the response. So the component could of course insist on having a navigation child node to dispatch rendering to as follows: RequestDispatcher rd = request.getRequestDispatcher("navigation");
rd.include(request, response);
| ||||||||||||||||||||||||||||||
Unsubscribe or edit your notifications preferences
