I have a resource I want to expose that has a constructor with parameters for injection. However I'm not using any injection framework, and I've got Jetty embedded.
Right now Jetty scans for Resources with this:
ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/server");
ServletHolder jerseyServletHolder = new ServletHolder(ServletContainer.class);
jerseyServletHolder.setInitParameter("com.sun.jersey.config.property.packages", "my.package.to.scan");
servletContextHandler.addServlet(jerseyServletHolder, "/*");
But it prevents me from injecting anything in the constructor, so I have to use a default constructor.
I'd like to specify my own instance to pass to my resource constructor. Is there a way to instantiate the resource manually and add it to the servlet container?
Is it possible to do something like this :
MyRestResource resource = new MyRestResource(param1, param2);
servletContextHandler.addServlet(resource);
or something like that?
You can inject dependencies into Jersey resources by registering a (Jersey) ServletContainer with a customized ResourceConfig. Please have a look at the code below as an example of creating a TimeResource class with a clock injected into it via a constructor.
public void start() {
server = new Server(6666);
ServletContextHandler handler = new ServletContextHandler();
handler.setContextPath("");
// adds Jersey Servlet with a customized ResourceConfig
handler.addServlet(new ServletHolder(new ServletContainer(resourceConfig())), "/*");
server.setHandler(handler);
try {
server.start();
} catch (Exception e) {
throw new RuntimeException("Could not start the server", e);
}
}
private ResourceConfig resourceConfig() {
// manually injecting dependencies (clock) to Jersey resource classes
return new ResourceConfig().register(new TimeResource(clock));
}
A full example with source code is available under:
http://unclejamal.github.io/2013/09/18/manual-dependency-injection-with-jersey-and-embedded-jetty.html
If MyRestResource
is a Servlet
, then you can use the existing servlet holder constructor.
ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/server");
ServletHolder jerseyServletHolder = new ServletHolder(ServletContainer.class);
jerseyServletHolder.setInitParameter("com.sun.jersey.config.property.packages", "my.package.to.scan");
servletContextHandler.addServlet(jerseyServletHolder, "/*");
MyRestResource resource = new MyRestResource(param1, param2);
// wrap resource in a ServletHolder
ServletHolder resourceHolder = new ServletHolder(resource);
// assign resource to a Servlet pathSpec
servletContextHandler.addServlet(resourceHolder, "/rest");
If you have a servlet, and want to access something setup at startup time, use the ContextHandler.setAttribute(String, Object) and ServletContext.getAttribute(String) techniques.
In your server startup
ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/server");
ServletHolder jerseyServletHolder = new ServletHolder(ServletContainer.class);
jerseyServletHolder.setInitParameter("com.sun.jersey.config.property.packages", "my.package.to.scan");
servletContextHandler.addServlet(jerseyServletHolder, "/*");
MyRestResource resource = new MyRestResource(param1, param2);
// Set resource as a context attribute
servletContextHandler.setAttribute("rest-1", resource);
Then access is later from the servlet api
ServletContext ctx = servletRequest.getServletContext();
MyRestResource resource = (MyRestResource) ctx.getAttribute("rest-1");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With