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.