Register a custom servlet
Question
How you can register a custom servlet?
Answer
A way would be to use an HTTP(s) servlet listener, where you can register servlets with spring bean. For that, you have to define a servlet listener (as OSGi reference) and the servlet directly in spring-like:
<bean id="versionServlet" class="org.jahia.modules.version.servlet.spring.VersionServlet"/> <bean id="httpServiceListener" class="org.jahia.modules.version.servlet.spring.HttpServiceListener"> <property name="versionServlet" ref="versionServlet" /> </bean> <osgi:reference id="httpService" interface="org.osgi.service.http.HttpService"> <osgi:listener ref="httpServiceListener" bind-method="onBind" unbind-method="onUnbind" /> </osgi:reference>
In the example the VersionServlet is a simple servlet, which just returns the installed Jahia version:
public class VersionServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private HttpService httpService; public VersionServlet() { } public void postConstruct() { } public void preDestroy() { } public void setHttpService(HttpService httpService) { this.httpService = httpService; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println(Jahia.VERSION); } }
The listener registers the servlet on the HttpService in the onbind method like:
public void onBind(ServiceReference serviceReference) { // note : we don't use the passed service reference because it is a proxy class that we cannot use to retrieve the // real service object, so we simply look it up again ServiceReference realServiceReference = bundleContext.getServiceReference(HttpService.class.getName()); HttpService httpService = (HttpService) bundleContext.getService(realServiceReference); try { httpService.registerServlet("/org.jahia.modules.version.servlet.spring", versionServlet, null, null); logger.info("Successfully registered custom servlet at /modules/org.jahia.modules.version.servlet.spring"); } catch (ServletException e) { e.printStackTrace(); } catch (NamespaceException e) { e.printStackTrace(); } }
For sure in the onUnbind method, you have to deregister the servlet.
When you call http(s)://server:port/modules/org.jahia.modules.version.servlet.spring you will get the current version number of the installed jahia.
Another way to register the servlet without spring would be to use a ModuleActivator. You can define in pom.xml an activator class which is called when the module is started:
<Bundle-Activator>org.jahia.modules.internal.ServletModuleActivator</Bundle-Activator>
So the class would look like:
..... public class ServletModuleActivator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { ServiceReference realServiceReference = bundleContext.getServiceReference(HttpService.class.getName()); HttpService httpService = (HttpService) bundleContext.getService(realServiceReference); try { httpService.registerServlet("/org.jahia.modules.version.servlet.spring", versionServlet, null, null); logger.info("Successfully registered custom servlet at /modules/org.jahia.modules.version.servlet.spring"); } catch (ServletException e) { e.printStackTrace(); } catch (NamespaceException e) { e.printStackTrace(); } } ....
On startup of the module, the servlet will be registered. In this case, you don't need the spring config and the HttpService class.