felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Apache Felix Http Service
Date Mon, 05 Oct 2009 16:01:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=FELIX&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/FELIX/Apache+Felix+Http+Service">Apache
Felix Http Service</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~srs">Sten
Roger Sandvik</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <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>Documentation of Http Service 2.0.x in progress.</p></td></tr></table></div>


<h1><a name="ApacheFelixHttpService-ApacheFelixHttpService"></a>Apache Felix
Http Service</h1>

<p>This is an implementation of the Http Service Specification as described in chapter
102 of the OSGi Compendium. The goal is to provide a standard and simplified way to register
servlets and resources in a Servlet container, and to associate them with URIs. It also implement
a non-standard extension for registering servlet filters as well as a whiteboard implementation.
Complete set of features:</p>

<ul>
	<li>Standard Http Service implementation.</li>
	<li>Extended Http Service implementation that allows for servlet filter registration.</li>
	<li>Run either with Jetty or inside your own application server using the servlet bridge.</li>
	<li>A whiteboard implementation for easy registration of servlets and filters.</li>
	<li>One complete bundle that includes everything to simplify deployment.</li>
</ul>


<h2><a name="ApacheFelixHttpService-Installing"></a>Installing</h2>

<p>The Apache Felix Http project includes several bundles. </p>

<ul>
	<li>org.apache.felix.http.jetty - Http Service implementation that is embedding Jetty
server.</li>
	<li>org.apache.felix.http.whiteboard - Whiteboard implementation that uses any Http
Service implementation.</li>
	<li>org.apache.felix.http.bridge - Http Service implementation that uses the host applicaiton
server (bridged mode). Must be used with proxy.</li>
	<li>org.apache.felix.http.bundle - All in one bundle that includes all of the above.</li>
	<li>org.apache.felix.http.proxy - Proxy that is needed inside WAR when deployed inside
an application server.</li>
</ul>


<p>So, in most cases you could just use <b>org.apache.felix.http.bundle</b>
and forget about all the other ones.</p>

<h2><a name="ApacheFelixHttpService-UsingtheHttpService"></a>Using the HttpService</h2>

<p>The main components provided by the Apache Felix Http Service bundle are:</p>
<ul>
	<li><tt>HttpService</tt> - Service used to dynamically register resources
and servlets</li>
	<li><tt>HttpContext</tt> - Additional (optional) component to handle authentication,
resource and mime type mappings</li>
</ul>


<p>Servlets created for the OSGi HTTP service don't need to have any reference to the
OSGi specification (they only need to conform to the Servlet specification), like in the example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class HelloWorld <span class="code-keyword">extends</span>
HttpServlet
{
	@Override
	<span class="code-keyword">protected</span> void doGet(HttpServletRequest req,
HttpServletResponse resp) <span class="code-keyword">throws</span> ServletException,
IOException 
	{
           resp.getWriter().write(<span class="code-quote">"Hello World"</span>);
	
	}	
}
</pre>
</div></div>

<p>To register a Servlet and map it to a URI, you need to retrieve the <tt>HttpService</tt>
and call its <tt>registerServlet</tt> method:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">implements</span>
BundleActivator
{
	<span class="code-keyword">public</span> void start(BundleContext context) <span
class="code-keyword">throws</span> Exception 
	{
		ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
		<span class="code-keyword">if</span> (sRef != <span class="code-keyword">null</span>)
		{
			HttpService service = (HttpService) context.getService(sRef);
			service.registerServlet(<span class="code-quote">"/hello"</span>, <span
class="code-keyword">new</span> HelloWorld(), <span class="code-keyword">null</span>,
<span class="code-keyword">null</span>);
		}
	}
</pre>
</div></div>

<p>In the same way, you can unregister a Servlet (for instance, in the <tt>stop</tt>
method of the Bundle Activator) calling the <tt>HttpService.unregister</tt> method.</p>

<p>As you notice in the example above, the <tt>registerServlet</tt> method
accepts four parameters:</p>
<ul>
	<li>the Servlet alias</li>
	<li>the Servlet instance</li>
	<li>an additional configuration Map</li>
	<li>an HttpContext</li>
</ul>


<p>The Servlet alias must begin with a slash and must not end with a slash. When a request
is processed, the Http Service will try to exact match the requested URI with a registered
Servlet. If not existent, it will remove the last '/' in the URI and everything that follows,
and try to match the remaining part, and so on.</p>

<p>An additional configuration Map can be optionally specified; if present, all the
parameters contained will be copied in the ServletContext object. </p>

<p>Finally, an HttpContext object can be optionally specified to handle authentication,
mime type and resource mapping. The <tt>HttpContext</tt> interface is quite simple:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
HttpContext
{
   <span class="code-object">String</span> getMimeType(java.lang.<span class="code-object">String</span>
name); <span class="code-comment">//Returns the mime type of the specified resource
</span>   URL getResource(java.lang.<span class="code-object">String</span>
name);   <span class="code-comment">//Returns the URL to retrieve the specified resource
</span>   <span class="code-object">boolean</span> handleSecurity(HttpServletRequest
request, HttpServletResponse response); <span class="code-comment">//Manages security
<span class="code-keyword">for</span> the specified request
</span>}
</pre>
</div></div>

<p>The use of a custom HttpContext is typical when you want to serve static contents
with the HTTP Service. Let's see first the simplest example of resource registration (without
<tt>HttpContext</tt>)</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">implements</span>
BundleActivator
{
	<span class="code-keyword">public</span> void start(BundleContext context) <span
class="code-keyword">throws</span> Exception 
	{
		ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
		<span class="code-keyword">if</span> (sRef != <span class="code-keyword">null</span>)
		{
			HttpService service = (HttpService) context.getService(sRef);
			service.registerResources(<span class="code-quote">"/<span class="code-keyword">static</span>"</span>,
<span class="code-quote">"/etc/www"</span>, <span class="code-keyword">null</span>);
		}
	}
</pre>
</div></div>

<p>As a result of the <tt>service.registerResources("/static", "/etc/www", null)</tt>
code, all the files available under <tt>/etc/www</tt> will be exposed under <tt>/static</tt>
(f.i.  <a href="http://localhost:8080/static/001.jpg" rel="nofollow">http://localhost:8080/static/001.jpg</a>
will render the /etc/www/001.jpg). However, the example above can be simplistic in practice;
the HttpContext object is the solution to customize the resource handling.</p>

<p>For instance, you can set the define more complex URI to file mappings overriding
the <tt>HttpContext.getResource</tt> method, or the correct mime type implementing
the method <tt>HttpContext.getMimeType</tt> like in the example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    <span class="code-comment">//....
</span>
	<span class="code-keyword">public</span> <span class="code-object">String</span>
getMimeType(<span class="code-object">String</span> file) 
	{  
	   <span class="code-keyword">if</span> (file.endsWith(<span class="code-quote">".jpg"</span>)
	   {  
	      <span class="code-keyword">return</span> <span class="code-quote">"image/jpeg"</span>;
 
	   } 
	   <span class="code-keyword">else</span> <span class="code-keyword">if</span>
(file.endsWith(<span class="code-quote">".png"</span>)) 
	   {  
	      <span class="code-keyword">return</span> <span class="code-quote">"image/png"</span>;
 
	   } 
	   <span class="code-keyword">else</span> 
	   {  
	      <span class="code-keyword">return</span> <span class="code-quote">"text/html"</span>;
 
	   }  
	}  
	
	<span class="code-comment">//....</span>
</pre>
</div></div>

<p>If you implement a customized HttpContext object, don't forget to specify it as third
parameter of the <tt>registerResources</tt> method invocation:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">implements</span>
BundleActivator
{
	<span class="code-keyword">public</span> void start(BundleContext context) <span
class="code-keyword">throws</span> Exception 
	{
		ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
		<span class="code-keyword">if</span> (sRef != <span class="code-keyword">null</span>)
		{
			HttpService service = (HttpService) context.getService(sRef);
			HttpContext myHttpContext = <span class="code-keyword">new</span> MyHttpContext());
			service.registerResources(<span class="code-quote">"/<span class="code-keyword">static</span>"</span>,
<span class="code-quote">"/etc/www"</span>, myHttpContext);
		}
	}
</pre>
</div></div>

<h2><a name="ApacheFelixHttpService-UsingtheExtHttpService"></a>Using the
ExtHttpService</h2>

<p>To be able to register filters, it is possible to get hold of <tt>org.apache.felix.http.api.ExtHttpService</tt>.
This is exported by both jetty and the bridged implementation. Let's see the simplest example
of a filter registration.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">implements</span>
BundleActivator
{
	<span class="code-keyword">public</span> void start(BundleContext context) <span
class="code-keyword">throws</span> Exception 
	{
		ServiceReference sRef = context.getServiceReference(ExtHttpService.class.getName());
		<span class="code-keyword">if</span> (sRef != <span class="code-keyword">null</span>)
		{
			ExtHttpService service = (ExtHttpService) context.getService(sRef);
			service.registerFilter(<span class="code-keyword">new</span> HelloWorldFilter(),
<span class="code-quote">"/hello/.*"</span>, <span class="code-keyword">null</span>,
0, <span class="code-keyword">null</span>);
		}
	}
</pre>
</div></div>

<p>Notice the pattern for filters is using regular expressions. So <tt>.&#42;</tt>
is the same as a simple <tt><br clear="all" />*</tt> using standard servlet
patterns. </p>

<h2><a name="ApacheFelixHttpService-ConfigurationProperties"></a>Configuration
Properties</h2>

<p>The service can both be configured using OSGi environment properties and using Configuration
Admin. The service PID for this service is <tt>"org.apache.felix.http"</tt>. If
you use both methods, Configuration Admin takes precedence. The following properties can be
used (some legacy property names still exist but are not documented here on purpose):</p>

<ul>
	<li><tt>org.osgi.service.http.port</tt> - The port used for servlets and
resources available via HTTP. The default is <tt>80</tt>.</li>
	<li><tt>org.osgi.service.http.port.secure</tt> - The port used for servlets
and resources available via HTTPS. The default is <tt>443</tt>.</li>
	<li><tt>org.apache.felix.http.nio</tt> - Flag to enable the use of NIO
instead of traditional IO. One consequence of using NIO with HTTPS is that the bundle needs
at least a Java 5 runtime. The default is <tt>true</tt>.</li>
	<li><tt>org.apache.felix.http.svcprop.port</tt> - The name of the property
to use to set the HTTP port. The default is <tt>org.osgi.service.http.port</tt>.</li>
	<li><tt>org.apache.felix.http.svcprop.port.secure</tt> - The name of the
property to use to set the HTTPS port. The default is <tt>org.osgi.service.http.port.secure</tt>.</li>
	<li><tt>org.apache.felix.http.enable</tt> - Flag to enable the use of HTTP.
The default is <tt>true</tt>.</li>
	<li><tt>org.apache.felix.https.enable</tt> - Flag to enable the user of
HTTPS. The default is <tt>false</tt>.</li>
	<li><tt>org.apache.felix.https.keystore</tt> - The name of the file containing
the keystore.</li>
	<li><tt>org.apache.felix.https.keystore.password</tt> - The password for
the keystore.</li>
	<li><tt>org.apache.felix.https.keystore.key.password</tt> - The password
for the key in the keystore.</li>
	<li><tt>org.apache.felix.https.truststore</tt> - The name of the file containing
the truststore.</li>
	<li><tt>org.apache.felix.https.truststore.password</tt> - The password
for the truststore.</li>
	<li><tt>org.apache.felix.https.clientcertificate</tt> - Flag to determine
if the HTTPS protocol requires, wants or does not use client certificates. Legal values are
<tt>needs</tt>, <tt>wants</tt> and <tt>none</tt>. The
default is <tt>none</tt>.</li>
	<li><tt>org.apache.felix.http.debug</tt> - Flag to enable debugging for
this service implementation. The default is <tt>false</tt>.</li>
</ul>


<p>Additionally, the all-in-one bundle uses the following environment properties:</p>

<ul>
	<li><tt>org.apache.felix.http.jettyEnabled</tt> - True to enable jetty
as the http container. The default is <tt>false</tt>.</li>
	<li><tt>org.apache.felix.http.whiteboardEnabled</tt> - True to enable the
whiteboard implementation. The default is <tt>false</tt>.</li>
</ul>


<h2><a name="ApacheFelixHttpService-Examples"></a>Examples</h2>

<p>A set of simple examples illustrating the various features are available. </p>

<ul>
	<li>Filter registration sample: <a href="http://svn.apache.org/repos/asf/felix/trunk/http/samples/filter/"
rel="nofollow">http://svn.apache.org/repos/asf/felix/trunk/http/samples/filter/</a></li>
	<li>Servlet bridge sample: <a href="http://svn.apache.org/repos/asf/felix/trunk/http/samples/bridge/"
rel="nofollow">http://svn.apache.org/repos/asf/felix/trunk/http/samples/bridge/</a></li>
	<li>Whiteboard sample: <a href="http://svn.apache.org/repos/asf/felix/trunk/http/samples/whiteboard/"
rel="nofollow">http://svn.apache.org/repos/asf/felix/trunk/http/samples/whiteboard/</a></li>
</ul>


     </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/FELIX/Apache+Felix+Http+Service">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=110503&revisedVersion=11&originalVersion=10">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Http+Service?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message