incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Sling API
Date Tue, 25 Aug 2009 09:30:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+API">Sling
API</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~bdelacretaz">Bertrand
Delacretaz</a>
    </h4>
     Added note about SlingRequestPathInfoTest
          <div id="versionComment" class="noteMacro" style="display:none; padding: 5px;">
     Added note about SlingRequestPathInfoTest<br />
     </div>
          <br/>
     <div class="notificationGreySide">
         <h1><a name="SlingAPI-TheSlingAPI"></a>The Sling API</h1>


<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Work In Progress</b><br
/><p>The contents of this page is being created at the moment. It contains incomplete
and partially wrong information as the text is adapted from the contents of the <a href="/confluence/pages/createpage.action?spaceKey=SLINGxSITE&amp;title=Component+API&amp;linkCreation=true&amp;fromPageId=76172"
class="createlink">Component API</a> documentation page.</p></td></tr></table></div>


<h2><a name="SlingAPI-Introduction"></a>Introduction</h2>

<p>The <em>Sling API</em> defines a presentation framework to build Web
Applications. As such the Sling API builds upon the Servlet API but extends the latter with
new functionality:</p>

<ul>
	<li>A web page may be built from many different pieces. This aggregation of different
pieces is comparable to the functionality provided by the Portlet API. In contrast to the
latter, though, the pieces may themselves be aggregates of yet more pieces. So a single web
page response may consist of a tree of pieces.</li>
	<li>Just like the Servlet API and the Portlet API the Sling API mainly defines a Java
based framework. Yet the Sling API comes with the intention of supporting scripting built.</li>
	<li>In contrast to the Servlet API and the Portlet API, the Sling API is resource centric.
That is, the request URL does not address a servlet or a portlet but a resource represented
by an instance of the <tt>org.apache.sling.api.resource.Resource</tt> interface.
From this resource the implementation of the Sling API will derive a <tt>javax.servlet.Servlet</tt>
or <tt>org.apache.sling.api.scripting.SlingScript</tt> instance, which is used
to handle the request.</li>
</ul>


<p>An implementation of the presentation framework defined by the Sling API is called
a <em>Sling Framework</em>. The Apache Sling project actually contains two implementations
of this API: <em>microsling</em> and <em>Sling</em>. microsling (note
the lowercase <em>m</em>) implements the same request processing mechanisms as
<em>Sling</em> but is very hardcoded. It serves well as a rapid development environment
as it is quickly set up, easy to handle and shows results very easily. Sling on the other
hand is based on an OSGi framework and very flexible, allowing the extension of the system
in various ways.</p>



<h2><a name="SlingAPI-GoingResourceCentric"></a>Going Resource Centric</h2>

<p>Traditional web applications are built around the notion of a traditional application
which is converted into an application which may be used using a Web Browser. Web applications
consist of a series of servlets and JSP scripts, which are called based on configuration in
the web application deployment descriptor. Such applications are generally based on some internal
database or some static filesystem content.</p>

<p>The Sling API on the other hand looks more like a traditional web server from the
outside, which delivers more or less static content. Thus, while the traditional web application
uses the request URL to select a piece of code to execute, the Sling API uses the URL to select
a resource to be delivered.</p>



<h3><a name="SlingAPI-ComparsiontotheServletAPI"></a>Comparsion to the Servlet
API</h3>

<p>The Sling API builds upon the Servlet API. Generally a Sling Framework will run inside
a Servlet Container and be manifested towards the Servlet Container as a single Servlet, which
dispatches requests to the Servlets and Scripts depending on the request URLs.</p>

<p>Response rendering may itself be a multi-step operation. Depending on the Servlets
and Scripts, the rendering may include dispatching for child (or even foreign) Resources.</p>



<h3><a name="SlingAPI-ComparisiontothePortletAPI"></a>Comparision to the
Portlet API</h3>

<p>Unlike the Portlet API, which defines one single level of portlet hierarchy - portlets
are just pieces residing besides each other - the Sling API allows for hierarchic structuring
of Resources and hence Servlet and Script renderings. To support this structuring, the Sling
Framework does not control the rendering process of all elements on the page like the Portlet
Container does for the portlets. Instead only the Resource addressed by the request URL is
processed and it is left to the Servlet or Script rendering that Resource to dispatch other
Resource/Servlet/Script tupels to add more data to the response.</p>


<h3><a name="SlingAPI-ToIteratororToEnumeration"></a>To Iterator or To Enumeration</h3>

<p>With the advent of the Java Collection framework in Java 2, the <tt>Enumeration</tt>
has been superceded by the <tt>Iterator</tt>. So the natural choice for the Sling
API for methods to return enumeratable collection of objects would have be to declare the
use of <tt>Iterator</tt> instances. But because the Servlet API defines to use
<tt>Enumeration</tt> instances, the Sling API will also declare the use of <tt>Enumeration</tt>
instances for consistency with the Servlet API extended by the Sling API.</p>




<h2><a name="SlingAPI-RequestProcessing"></a>Request Processing</h2>

<p>Unlike traditional Servlet API request processing, a Sling API request is processed
by the Sling Framework in three basic steps:</p>

<ol>
	<li><b>Resource Resolution</b> - The Sling Framework derives a Resource
instance from the client request URL. The details of how to resolve the Resource. One possible
solution would be to map the request URL to a <a href="http://www.jcp.org/en/jsr/detail?id=170"
rel="nofollow">Java Content Repository</a> Node and return a Resource representing
that Node.</li>
	<li><b>Servlet and Script Resolution</b> - From the Resource created in
the first step, the Servlet or Script is resolved based on the type of the Resource. The resource
type is a simple string, whose semantics is defined by the Sling Framework. One possible definition
could be for the resource type to be the primary node type of the Node underlying the Resource.</li>
	<li><b>Input Processing and Response Generation</b> -  After getting the
Resource and the Servlet or Script, the <tt>service()</tt> method is called or
the script is evaluated to process any user supplied input and send the response to the client.
To structure the rendered response page, this method is responsible to include other resources.
See <em>Dispatching Requests</em> below for details. See <em>Error Handling</em>
below for a discussion on how exceptions and HTTP stati are handled.</li>
</ol>




<h3><a name="SlingAPI-URLdecomposition"></a>URL decomposition</h3>

<p>During the <em>Resource Resolution</em> step, the client request URL
is decomposed into the following parts:</p>

<ol>
	<li><b>Resource Path</b> -  The longest substring of the request URL resolving
to a Resource such that the resource path is either the complete request URL or the next character
in the request URL after the resource path is either a dot (<tt>.</tt>) or a slash
(<tt>/</tt>).</li>
	<li><b>Selectors</b> -  If the first character in the request URL after
the resource path is a dot, the string after the dot upto but not including the last dot before
the next slash character or the end of the request URL. If the resource path spans the complete
request URL or if a slash follows the resource path in the request URL, no seletors exist.
If only one dot follows the resource path before the end of the request URL or the next slash,
no selectors exist.</li>
	<li><b>Extension</b> -  The string after the last dot after the resource
path in the request URL but before the end of the request URL or the next slash after the
resource path in the request URL. If a slash follows the resource path in the request URL,
the extension is empty.</li>
	<li><b>Suffix Path</b> -  If the request URL contains a slash character
after the resource path and optional selectors and extension, the path starting with the slash
upto the end of the request URL is the suffix path. Otherwise, the suffix path is empty.</li>
</ol>


<p><b>Examples</b>: Assume there is a Resource at <tt>/a/b</tt>,
which has no children.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> URI </th>
<th class='confluenceTh'> Resource Path </th>
<th class='confluenceTh'> Selectors </th>
<th class='confluenceTh'> Extension </th>
<th class='confluenceTh'> Suffix </th>
</tr>
<tr>
<td class='confluenceTd'> /a/b                      </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> null       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.html                 </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> null       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.html              </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1    </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> null       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.s2.html           </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1.s2 </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> null       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b/c/d                  </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> /c/d       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.html/c/d             </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.html/c/d          </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1    </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.s2.html/c/d       </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1.s2 </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d       </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b/c/d.s.txt            </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> /c/d.s.txt </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.html/c/d.s.txt       </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> null  </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d.s.txt </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.html/c/d.s.txt    </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1    </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d.s.txt </td>
</tr>
<tr>
<td class='confluenceTd'> /a/b.s1.s2.html/c/d.s.txt </td>
<td class='confluenceTd'> /a/b </td>
<td class='confluenceTd'> s1.s2 </td>
<td class='confluenceTd'> html </td>
<td class='confluenceTd'> /c/d.s.txt </td>
</tr>
</tbody></table>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Automated
tests and examples</b><br /><p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/request/SlingRequestPathInfoTest.java"
rel="nofollow">SlingRequestPathInfoTest</a> demonstrates and tests this decomposition.
Feel free to suggest additional tests that help clarify how this works!</p></td></tr></table></div>

<h2><a name="SlingAPI-TheSlingHttpServletRequest"></a>The SlingHttpServletRequest</h2>

<p>The <tt>org.apache.sling.api.SlingHttpServletRequest</tt> interface defines
the basic data available from the client request to both action processing and response rendering.
The <tt>SlingHttpServletRequest</tt> extends the <tt>javax.servlet.http.HTTPServletRequest</tt>.</p>

<p>This section describes the data available from the <tt>SlingHttpServletRequest</tt>.
For a complete and normative description of the methods, refer to the Sling API JavaDoc. The
following information is represented for reference. In the case of differences between the
following descriptions and the Sling API JavaDoc, the latter takes precedence.</p>

<ol>
	<li><b>Resource access</b> - Resources may be accessed from the <tt>SlingHttpServletRequest</tt>
object through the following methods: <tt>getResource()</tt>, <tt>getResourceResolver()</tt>.</li>
	<li><b>Request URL information</b> - In addition to the standard <tt>HttpServletRequest</tt>
information the <tt>SlingHttpServletRequest</tt> provides access to the selectors,
extension and suffix through the <tt>getRequestPathInfo()</tt> method. Note that
the Resource path is not directly available form the <tt>SlingHttpServletRequest</tt>
object. Instead it is available through the <tt>Resource.getPath()</tt> method
of the Resource object retrieved through <tt>SlingHttpServletRequest.getResource()</tt>.</li>
	<li><b>Request Parameters</b> - To support user input submitted as <tt>multipart/form-data</tt>
encoded POST parameters, the Sling API intrduces the <tt>RequestParameter</tt>
interface allowing file uploads. Request parameters represented as <tt>RequestParameter</tt>
objects are returned by the following methods: <tt>getRequestParameter(String name)</tt>,
<tt>getRequestParameterMap()</tt>, <tt>getRequestParameters(String name)</tt>.</li>
	<li><b>Request Dispatching</b> - In addition to standard Serlvet API request
dispatching, the Sling API supports dispatching requests to render different Resources using
<tt>RequestDispatcher</tt> objects returned by the methods: <tt>getRequestDispatcher(Resource
resource)</tt> and <tt>getRequestDispatcher(Resource resource, RequestDispatcherOptions
options)</tt>.</li>
	<li><b>Miscellaneous</b> - Finally the ComponentRequest interface provides
the following methods: <tt>getCookie(String name)</tt>, <tt>getRequestProgressTracker()</tt>,
<tt>getResponseContentType()</tt>, <tt>getResponseContentTypes()</tt>,
<tt>getResourceBundle(Locale locale)</tt>, <tt>getServiceLocator()</tt>.</li>
</ol>


<p>The <tt>SlingHttpServletRequest</tt> objects are only valid during the
time of request processing. Servlets and Scripts must not keep references for later use. As
such, the <tt>SlingHttpServletRequest</tt> interface and its extensions are defined
to not be thread safe.</p>

<p><em>A note on HTTP Sessions</em>: The <tt>SlingHttpServletRequest</tt>
extends the <tt>HttpSerlvetRequest</tt> and thus supports standard HTTP sessions.
Be aware, though that Sessions are server side sessions and hence violate the sessionless
principle of REST and therefore should be used with care. It is almost always possible to
not use sessions.</p>


<h2><a name="SlingAPI-TheSlingHttpServletResponse"></a>The SlingHttpServletResponse</h2>

<p>The <tt>org.apache.sling.api.SlingHttpServletResponse</tt> interface
extends the <tt>javax.servet.http.HttpServletResponse</tt> interface and is currently
empty. It merely exists for symmetry with the <tt>SlingHttpServletRequest</tt>.</p>




<h2><a name="SlingAPI-TheResource"></a>The Resource</h2>

<p>The <tt>org.apache.sling.resource.Resource</tt> represents the data addressed
by the request URL. Resources may also be retrieved through the <tt>org.apache.sling.api.resource.ResourceResolver</tt>.
Usually this interface is not implemented by clients. In certain use cases we call <em>synthetic
Resource</em> if may be usefull to define a simple object implementing the <tt>Resource</tt>
interface. The Sling Framework does not care about the concrete implementation of the <tt>Resource</tt>
interface and rather uses the defined methods to access required information. The interface
defines the following methods:</p>

<ol>
	<li><b>getResourceType()</b> - Returns the type of the resource. This resource
type is used to resolve the Servlet or Script used to handle the request for the resource.</li>
	<li><b>getPath()</b> - Returns the path derived from the client request
URL which led to the creation of the Resource instance. See the <a href="#SlingAPI-URLdecompositionURLdecomposition">URL&#95;decomposition
URL decomposition</a> section above for more information. It is not required, that the
Resource path be a part of the original client request URL. The request URL may also have
been mapped to some internal path.</li>
	<li><b>getResourceMetadata()</b> - Returns meta data information about
the resource in a <tt>ResourceMetadata</tt> object.</li>
	<li><b>adaptTo(Class&lt;AdapterType&gt; type)</b> - Returns alternative
representations of the Resource. The concrete supported classes to which the Resource may
be adapted depends on the implementation. For example a Resource based on a JCR Node may support
being adapted to the underlying Node, an <tt>InputStream</tt>, an <tt>URL</tt>
or even to a mapped object through JCR Object Content Mapping.</li>
</ol>


<hr />



<h2><a name="SlingAPI-TheComponent"></a>The Component</h2>

<p>The <tt>org.apache.sling.component.Component</tt> interface defines the
API implemented to actually handle requests. As such the Component interface is comparable
to the =javax.servlet.Servlet= interface. Like those other interfaces, the Component interface
provides methods for life cycle management: <tt>init(ComponentContext context)</tt>,
<tt>destroy()</tt>.</p>



<h3><a name="SlingAPI-ProcessingtheRequest"></a>Processing the Request</h3>

<p>The Component Framework calls the <tt>service(ComponentRequest request, ComponentResponse
response)</tt> method of the Component to have the component process the request optionally
processing user input, rendering the response and optionally dispatch to other Content/Component
tuples to provide more response data.</p>



<h3><a name="SlingAPI-ContentanditsComponent"></a>Content and its Component</h3>

<p>The Content object and a Component form a pair, in which the Content object takes
the passive part of providing data to the Component and the Component takes the active part
of acting upon the Content object. As a consequence, there always exists a link between a
given implementation of the Content interface and a given implementation of the Component
interface.</p>

<p>This link is manifested by the Component identifier available from the Content object
through the <tt>Content.getComponentId()</tt> method on the one hand. On the other
hand, the link is manifested by the <tt>getContentClassName()</tt> and <tt>createContentInstance()</tt>
methods of the Component interface.</p>



<h3><a name="SlingAPI-ComponentLifecylce"></a>Component Lifecylce</h3>

<p>When a Component instance is created and added to the Component framework, the <tt>init(ComponentContext)</tt>
method is called to prepare and initialize the Component. If this method terminates abnormally
by throwing an exception, the Component is not used. The Component Framework implementation
may try at a later time to recreate the Component, intialize it and use it. If the Component
Framework tries to recreate the Component a new instance of the Component must be created
to be initialized and used.</p>

<p>When the Component has successfully been initialized, it may be referred to by Content
objects. When a client request is to be processed, the Content object is resolved and the
<tt>service</tt> method on the Component to which the Content object refers is
called. The <tt>service</tt> method may - and generally will - be called simultaneously
to handle different requests in different threads. As such, implementations of these methods
must be thread safe.</p>

<p>When the Component Framework decides to take a Component out of service, the <tt>destroy()</tt>
method is called to give the Component a chance to cleanup any held resources. The destroy
method must only be called by the Component Framework when no more request processing is using
the Component, that is no thread may be in the <tt>service</tt> method of a Component
to be destroyed. Irrespective of whether the destroy method terminated normally or abnormally,
the Component will not be used again.</p>

<p>The addition and removal of Components is at the discretion of the Component Framework.
A Component may be loaded at framework start time or on demand and my be removed at any time.
But only one single Component instance with the same Component identifier may be active at
the same time within a single Component Framework instance.</p>



<h3><a name="SlingAPI-TheComponentExtension"></a>The ComponentExtension</h3>

<p>To enhance the core functionality of Components, each Component may have zero, one
ore more Component Extensions attached. A Component Extensions is a Java object implementing
the <tt>org.apache.sling.component.ComponentExtension</tt> interface. This interface
just defines a <tt>getName()</tt> method to identify extensions.</p>

<p>The concrete implementation as well as instantiation and management of Component
Extensions is left to the Component Framework implementation with one restriction though:
The extensions must be available to the Component at the time the <tt>init(ComponentContext)</tt>
method is called may only be dropped after the <tt>destroy()</tt> method terminates.</p>

<p>The Component interface defines two methods to access Extensions: The <tt>getExtensions()</tt>
method returns a <tt>java.util.Enumeration</tt> of all ComponentExtension objects
attached to the component. If no Component Extension are attached to the Component, an empty
enumeration is returned. The <tt>getExtension(String name)</tt> returns the named
Component Extension attached to the Component or <tt>null</tt> if no such Component
Extension is attached to the Component.</p>

<p>Component Frameworks are allowed to share Component Extension instances of the same
name between different Component instances. Regardless of whether Component Extensions are
shared or not, they must be thread safe, as any Component Extension may be used within the
<tt>service</tt> method, which themselves may be called concurrently.</p>




<h2><a name="SlingAPI-RequestProcessingFilters"></a>Request Processing Filters</h2>

<p>Similar to the Servlet API providing filters for filtering requests and/or responses
the Component API provides the <tt>org.apache.sling.component.ComponentFilter</tt>
interface. The filters are called by a <tt>ComponentFilterChain</tt> and either
handle the request, manipulate the request and/or response object and finally forward the
request and response optionally wrapped to the <tt>ComponentFilterChain.doFilter(ComponentRequest,
ComponentResponse)</tt> method.</p>

<p>Like the <tt>Component}}s  filters have a defined lifecycle manifested by {{init</tt>
and <tt>destroy</tt> methods. When the filter enters the system, the Component
Framework calls the <tt>ComponentFilter.init(ComponentContext)</tt> method. Only
when this method completes successfully will the filter be put into action and be used during
request processing. When the filter leaves the system, the Component Framework removes the
filter from being used in filter chains and calls the <tt>ComponentFilter.destroy()</tt>
method. This method is not expected to throw any exceptions. The filter may be removed from
the Component Framework at the discretion of the Component Framework or because the filter
is being unregistered from the Component Framework by some means outside this specification.</p>

<p>This specification does not define how <tt>ComponentFilter</tt> objects
are registered with the Component Framework nor is it specified how the order in which the
filters are called is defined. Likewise it is outside this specification how the filter instances
registered with the Component Framework are configured.</p>



<h2><a name="SlingAPI-Sessions"></a>Sessions</h2>


<p>The <tt>org.apache.sling.component.ComponentSession</tt> interface provides
a way to identify a user across more than one request and to store transient information about
that user.</p>

<p>A component can bind an object attribute into a <tt>ComponentSession</tt>
by name. The <tt>ComponentSession</tt> interface defines two scopes for storing
objects: <tt>APPLICATION_SCOPE</tt>, <tt>COMPONENT_SCOPE</tt>. All
objects stored in the session using the <tt>APPLICATION_SCOPE</tt> must be available
to all the components, servlets and JSPs that belong to the same component application and
that handle a request identified as being a part of the same session. Objects stored in the
session using the <tt>COMPONENT_SCOPE</tt> must be available to the component
during requests for the same content that the objects where stored from. Attributes stored
in the <tt>COMPONENT_SCOPE</tt> are not protected from other web components of
the component application. They are just conveniently namespaced.</p>

<p>The component session extends the Servlet API <tt>HttpSession</tt>. Therefore
all <tt>HttpSession</tt> listeners do apply to the component session and attributes
set in the component session are visible in the <tt>HttpSession</tt> and vice
versa.</p>

<p>The attribute accessor methods without the <em>scope</em> parameter always
refer to <tt>COMPONENT_SCOPE</tt> attributes. To access <tt>APPLICATION_SCOPE</tt>
attributes use the accessors taking an explicit <tt>scope</tt> parameter.</p>

<p><em>A final note on Sessions</em>: Sessions are server side sessions
and hence violate the sessionless principle of REST and therefore should be used with care.
It is almost always possible to not use sessions.</p>



<h2><a name="SlingAPI-DispatchingRequests"></a>Dispatching Requests</h2>

<p>To include renderings of child Content objects, a <tt>org.apache.sling.component.ComponentRequestDispatcher</tt>
object may be retrieved from the ComponentContext with which the Component has been initialized
or from the ComponentRequest provided to the service method. Using this dispatcher the reponse
of rendering the Content may be included by calling the <tt>ComponentRequestDispatcher.include(ComponentRequest,
ComponentResponse)</tt> method.</p>

<p>This method is comparable to the <tt>RequestDispatcher.include(ServletRequest,
ServletResponse</tt> method of the Servlet API but dispatching by the <tt>ComponentRequestDispatcher</tt>
does not go through the servlet container and stays within the Component Framework.</p>

<p>The <tt>service</tt> method of included Components are called with an
instance of the <tt>ComponentRequest</tt> interface whose <tt>getContent()</tt>
returns the Content object for the included Content.</p>

<p>When a Component is included by another component the following request attributes
are set:</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> <b>Request Attributes</b> </th>
<th class='confluenceTh'> <b>Type</b> </th>
<th class='confluenceTh'> <b>Description</b> </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.sling.component.request.content</tt>
</td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> The <tt>Content</tt> instance to which the client
URL resolved. This attribute is set when included Components are being rendered and it is
not set for the Component directly addressed by the client request. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.sling.component.request.component</tt>
</td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> The <tt>Component</tt> instance for the <tt>Content</tt>
object to which the client URL resolved. This attribute is set when included Components are
being rendered and it is not set for the Component directly addressed by the client request.
</td>
</tr>
</tbody></table>


<h3><a name="SlingAPI-ErrorHandling"></a>Error Handling</h3>

<p>While processing requests, the <tt>service</tt> methods called may have
problems. Components have multiple options of reporting issues during processing to the client:</p>

<ul>
	<li>Set the status of the HTTP response calling the <tt>ComponentResponse.setStatus</tt>
method</li>
	<li>Send an error page calling the <tt>ComponentResponse.sendError</tt>
method</li>
	<li>Throw an exception</li>
</ul>



<p>If such an exception is thrown, the Component Framework must act upon the exception
in one of the following ways:</p>

<ul>
	<li>If the request is processed through Servlet API request inclusion, the exception
must be given back to the servlet container. A <tt>ComponentException</tt> is
just forwarded as a <tt>ServletException</tt>. This is a requirement of the Servlet
API specification which states for included requests:</li>
</ul>


<blockquote>
<p><b>SRV.8.5 Error Handling</b><br clear="all" />If the servlet that
is the target of a request dispatcher throws a runtime exception or a checked exception of
type ServletException or IOException, it should be propagated to the calling servlet. All
other exceptions should be wrapped as ServletExceptions and the root cause of the exception
set to the original exception, as it should not be propagated.</p></blockquote>

<ul>
	<li>Otherwise, the Component Framework may handle the error itself in a manner similar
to the error handling approach defined the Servlet API specification (Section SRV 9.9 Error
Handling of the Java Servlet Specification 2.4). Specifically the request attributes defined
by the Servlet API specification must be set for the error handler:</li>
</ul>


<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> <b>Request Attributes</b> </th>
<th class='confluenceTh'> <b>Type</b> </th>
<th class='confluenceTh'> <b>Description</b> </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.status_code</tt> </td>
<td class='confluenceTd'> <tt>java.lang.Integer</tt> </td>
<td class='confluenceTd'> The status code of the response. In the case of an exception
thrown from the <tt>service</tt>, the code is defined by the Component Framework.
</td>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.exception_type</tt> </td>
<td class='confluenceTd'> <tt>java.lang.Class</tt> </td>
<td class='confluenceTd'> The fully qualified name of the exception class thrown. This
attribute does not exist, if error handling does not result from an exception. This attribute
is maintained for backwards compatibility according to the Servlet API Specification. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.message</tt> </td>
<td class='confluenceTd'> <tt>java.lang.String</tt> </td>
<td class='confluenceTd'> The message of the exception thrown. This attribute does not
exist, if error handling does not result from an exception. This attribute is maintained for
backwards compatibility according to the Servlet API Specification. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.exception</tt> </td>
<td class='confluenceTd'> <tt>java.lang.Throwable</tt> </td>
<td class='confluenceTd'> The exception thrown. This attribute does not exist, if error
handling does not result from an exception. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.request_uri</tt> </td>
<td class='confluenceTd'> <tt>java.lang.String</tt> </td>
<td class='confluenceTd'> The request URL whose processing resulted in the error. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>javax.servlet.error.servlet_name</tt> </td>
<td class='confluenceTd'> <tt>java.lang.String</tt> </td>
<td class='confluenceTd'> The name of the servlet which yielded the error. The servlet
name will generally not have any significance inside the Component Framework. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.sling.component.error.componentId</tt>
</td>
<td class='confluenceTd'> <tt>java.lang.String</tt> </td>
<td class='confluenceTd'> The identifier of the Component whose <tt>service</tt>
method has caused the error. This attribute does not exist, if the Component Framework itself
caused the error processing. </td>
</tr>
</tbody></table>
<ul>
	<li>If the Component Framework decides to not handle the error itself, the exception
must be forwarded to the servlet container as a <tt>ComponentException</tt> wrapping
the original exception as its root cause.</li>
</ul>


<p>This specification does not define, how error handlers are configured and used if
the Component Framework provides error handling support. Likewise the Component Framework
may or may not implement support to handle calls to the <tt>ComponentResponse.sendError</tt>
method. The Component Framework may also use its own error handling also for errors resulting
from request processing failures, for example if authentication is required or if the request
URL cannot be resolved to a Content object.</p>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+API">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=76172&revisedVersion=2&originalVersion=1">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+API?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message