...
Apache Felix HTTP Service
This service bundle implements the Http HTTP Service Specification as described in chapter 102 of the OSGi Compendium. It uses Jetty as its implementation., embedding the Jetty servlet container. The goal of the OSGI HTTP Service is to provide a standard and simplified way to register servlets and resources in a Servlet container, and to associate them with URIs.
Installing the Apache Felix HTTP Service bundle
The Apache Felix HTTP Service bundle can be installed and executed in any R4 OSGi container, and requires only the OSGi R4 Compendium bundle as a prerequisite.
Using the HTTP Service
The main components provided by the Apache Felix HTTP Service bundle are:
HttpService
- Service used to dynamically register resources and servletsHttpContext
- Additional (optional) component to handle authentication, resource and mime type mappings
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:
Code Block |
---|
public class HelloWorld extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.getWriter().write("Hello World");
}
}
|
To register a Servlet and map it to a URI, you need to retrieve the HttpService
and call its registerServlet
method:
Code Block |
---|
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
if (sRef != null)
{
HttpService service = (HttpService) context.getService(sRef);
service.registerServlet("/hello", new HelloWorld(), null, null);
}
}
|
In the same way, you can unregister a Servlet (for instance, in the stop
method of the Bundle Activator) calling the HttpService.unregister
method.
As you notice in the example above, the registerServlet
method accepts four parameters:
- the Servlet alias
- the Servlet instance
- an additional configuration Map
- an HttpContext
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.
An additional configuration Map can be optionally specified; if present, all the parameters contained will be copied in the ServletContext object.
Finally, an HttpContext object can be optionally specified to handle authentication, mime type and resource mapping. The HttpContext
interface is quite simple:
Code Block |
---|
public interface HttpContext
{
String getMimeType(java.lang.String name); //Returns the mime type of the specified resource
URL getResource(java.lang.String name); //Returns the URL to retrieve the specified resource
boolean handleSecurity(HttpServletRequest request, HttpServletResponse response); //Manages security for the specified request
}
|
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 HttpContext
)
Code Block |
---|
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
if (sRef != null)
{
HttpService service = (HttpService) context.getService(sRef);
service.registerResources("/static", "/etc/www", null);
}
}
|
As a result of the service.registerResources("/static", "/etc/www", null)
code, all the files available under /etc/www
will be exposed under /static
(f.i. http://localhost:8080/static/001.jpg 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.
For instance, you can set the define more complex URI to file mappings overriding the HttpContext.getResource
method, or the correct mime type implementing the method HttpContext.getMimeType
like in the example:
Code Block |
---|
//....
public String getMimeType(String file)
{
if (file.endsWith(".jpg")
{
return "image/jpeg";
}
else if (file.endsWith(".png"))
{
return "image/png";
}
else
{
return "text/html";
}
}
//....
|
If you implement a customized HttpContext object, don't forget to specify it as third parameter of the registerResources
method invocation:
Code Block |
---|
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
ServiceReference sRef = context.getServiceReference(HttpService.class.getName());
if (sRef != null)
{
HttpService service = (HttpService) context.getService(sRef);
HttpContext myHttpContext = new MyHttpContext());
service.registerResources("/static", "/etc/www", myHttpContext);
}
}
|
Configuration Properties
The service can both be configured using OSGi environment properties and using Configuration Admin. The service PID for this service is "org.apache.felix.http"
. 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):
...