Written by The Jahia Team
 
Developers
   Estimated reading time:

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.

Related links