poniedziałek, 11 stycznia 2010

Servlety w OSGi

Platforma OSGi pozwala na dodanie do naszej aplikacji możliwości jakie oferują serwery aplikacji - uruchamianie własnych servletów.

Po utworzeniu nowego projektu tworzymy klasę servletu - czyli klasę dziedziczącą z "javax.servlet.http.HttpServlet". Prawdopodobnie w MANIFEST.MF będziemy musieli dodać deklarację importującą pakiet "javax.servlet.http" oraz "javax.servlet". Może ona wyglądać np tak:


package sample.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SampleServlet extends HttpServlet{
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().println("Hello world");
resp.getWriter().close();
}
}




Następnie w aktywatorze naszego pakunku nasłuchujemy na pojawienie się usługi HttpService. Gdy to się stanie rejestrujemy w niej nasz servlet.


package sample.servlet;

import javax.servlet.ServletException;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

public class Activator implements BundleActivator {
ServiceTracker httpServiceTracker;
ServiceTrackerCustomizer httpServiceTrackerCustomizer;
HttpService httpService;
ServiceReference httpServiceReference;

public void start(final BundleContext context) throws Exception {
httpServiceTrackerCustomizer = new ServiceTrackerCustomizer() {
@Override
public void removedService(ServiceReference reference, Object service) {
httpService.unregister("/hello");
httpService = null;
httpServiceReference = null;
}

@Override
public void modifiedService(ServiceReference reference, Object service) {
}

@Override
public Object addingService(ServiceReference reference) {
httpService = (HttpService) context.getService(reference);
httpServiceReference = reference;
try {
httpService.registerServlet("/hello", new SampleServlet(), null, null);
} catch (ServletException e) {
e.printStackTrace();
} catch (NamespaceException e) {
e.printStackTrace();
}
return httpService;
}
};
httpServiceTracker = new ServiceTracker(context, HttpService.class.getName(), httpServiceTrackerCustomizer);
httpServiceTracker.open();
}

public void stop(BundleContext context) throws Exception {
httpServiceTracker.close();
if(httpService != null){
httpService.unregister("/hello");
context.ungetService(httpServiceReference);
httpService = null;
httpServiceReference = null;
}
}
}


W metodzie start (która zostanie wywołana przez OSGi podczas uruchamiania pakunku tworzymy własny ServiceTrackerCustomizer, który w przypadku odnalezienia usługi (jak się za chwilę okaże chodzi o HttpService) zarejestruje w niej nasz servlet ("httpService.registerServlet("/hello", new SampleServlet(), null, null);"), natomiast, gdy stanie się ona niedostępna servlet zostanie wyrejestrowany. Poniżej tworzymy obiekt ServiceTracker, któremu przekazujemy nazwę usługi jaką chcemy obserwować (właśnie tutaj definiujemy, że ma to być HttpService) i ServiceTrackerCustomizer utworzony wcześniej.

W metodzie stop sprzątamy po sobie, czyli wyrejestrowujemy servlet i deklarujemy, że nie będziemy korzystać z usługi HttpService (metoda unget).

Nim uruchomimy servlet musimy jeszcze nanieść poprawki do MANIFEST.MF deklarując import pakietów "org.osgi.framework", "org.osgi.service.http" oraz "org.osgi.util.tracker".

Pora na uruchomienie aplikacji. W Eclipse tworzę nową konfigurację uruchomienia typu "OSGi Framework", wskazuje w niej mój pakunek i naciskam przycisk "Add Required Bundles" - Eclipse dodaje za mnie wszystkie niezbędne zależności. Ponadto ręcznie wskazuje pakunek org.eclipse.equinox.http.jetty. Naciskam Run i w przeglądarce przechodze pod adres http://localhost/hello.

A dla niekorzystających z Eclipse screen z zależnościami niezbędnymi do poprawnego uruchomienia pakunku.

Brak komentarzy:

Prześlij komentarz