Issue
In an existing Java SE project, my colleagues had implemented a bunch of web services in Restlet, relying on an internal server implementation. This turned out to be inadequate in the long run, so we migrated to a server engine based on jetty 9, with the great drawback that Restlet did not support it back then. This didn't stop the team, and now quite a few "raw" HTTP servlets were implemented with our business logic.
As this turned out to become a frustrating way of implementing web services, we now wish to have Restlet back for future services and make them work alongside these servlets. My research revealed no big clues on making such an integration, with the exception that a Request and Response wrapper to the HTTP counterparts is still under way, and marked as unplanned. Furthermore, the amount of existing work on these servlets is significant, which is why I'm putting conversion to Restlet resources as a last resort.
To sum the question up, how can I make a Restlet Application work alongside HTTP servlets in the same server? Is there a way in Java SE to attach a Rest application to a servlet container? Or thinking the other way around, is there a way to attach raw servlets to an Application with some extra resort, like a Servlet-to-Resource wrapper that could be applied to any HTTP servlet? Any feasible, non-invasive solution may be accepted.
Solution
It seems that the org.restlet.ext.servlet
package is compatible with the Java SE edition of Restlet, even though it is listed in the Java EE group. Here are the steps one would follow:
Create a ServletAdapter
, which converts HTTP servlet requests and responses to high-level restlet representations. The documentation itself suggests to encapsulate it.
public class RestletHttpServlet extends HttpServlet {
private ServletAdapter adapter;
private final Restlet restlet;
public RestletHttpServlet(Restlet restlet) {
this.restlet = restlet;
}
@Override
public void init() throws ServletException {
super.init();
this.adapter = new ServletAdapter(getServletContext());
this.restlet.setContext(this.adapter.getContext());
this.adapter.setNext(this.restlet);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.adapter.service(req, resp);
}
}
With this helper class, simply create new restlets and attach them with the servlet API (using context handlers here):
Restlet myRestlet = ...
ServletContextHandler cHandler = new ServletContextHandler();
cHandler.addServlet(new ServletHolder(new RestletHttpServlet(myRestlet)), "/myRestlet/*");
ContextHandlerCollection contextHandlers = new ContextHandlerCollection();
contextHandlers.setHandlers(new Handler[]{cHandler});
server.setHandler(contextHandlers);
Routers, resources and template paths seem to work as well. Making the first restlet an Application
is also possible and often helpful for a complete context initialization.
Answered By - E_net4 the candidate supporter