Get ServletContext in JAX-RS resource
Asked Answered
C

5

67

I'm playing around with JAX-RS, deploying on Tomcat. It's basically:

@Path("/hello")
@Produces({"text/plain"})
public class Hellohandler {

    @GET
    public String hello() {
        return "Hello World";
    }

}

Is there any way I can get hold of the ServletContext within my JAX-RS resource?

Crellen answered 29/11, 2009 at 3:9 Comment(0)
D
103

Furthermore, @Resource annotation might not work. Try this

@javax.ws.rs.core.Context 
ServletContext context;

The injection doesn't happen until you hit the service method

public class MyService {
    @Context ServletContext context;

    public MyService() {
         print("Constructor " + context);  // null here     
    }

    @GET
    @Path("/thing") {               
             print("in  wizard service " + context); // available here
Disordered answered 29/11, 2009 at 5:55 Comment(9)
which javax.ws.rs class do I use as a servlet handler ?Crellen
Not really getting you by this. You are already having a class which handles HTTP GET requests. Please elaborate more what do mean by Servlet Handler. Cheers.Disordered
A servlet container needs a servlet to handle requests. com.sun.ws.rest.spi.container.servlet.ServletContainer takes care of handling the requests and dispatch them to my annotaded classes. You imply I should not use com.sun.* classes, so what then should I use ?Crellen
Why not use any popular servlet container like Jetty or Tomcat?Disordered
As the question says I am using Tomcat. Tomcat will not blindly recognize my jax-rs annotated classes. It will need a servlet to handle the requests. Same deal with Jetty.Crellen
com.sun.ws.rest.spi.container.servlet.ServletContainer is what you use if you're using the jax-rs reference implementations. Other implementation will require you to use their implementation specific servlet. Alternativly, you can(according to the spec) derive from javax.ws.rs.core.Application and specify that as your servlet handler, though that is not supported by implementations yet..Minima
I agree with 'nos' here. I merely said that because they discourage to use classes under com.sun...Disordered
How about other implementations? Namely Jersey. The package would be com.sun.jersey.spi.container.servlet.ServletContainer in that case. Although, this also starts like com.sun..., but I think this must be excluded from those they discouraged. I don't know why they come up with this package scheme, when they themselves discourge the thing. Its confusing.Disordered
Note: this will also work as a parameter on specific methods: @Context ServletContext contextBrom
I
9

As others have noted, the servletContext can be injected at the field level. It can also be injected at the method level:

public static class MyService {
    private ServletContext context;
    private int minFoo;

    public MyService() {
        System.out.println("Constructor " + context); // null here
    }

    @Context
    public void setServletContext(ServletContext context) {
        System.out.println("servlet context set here");
        this.context = context;

        minFoo = Integer.parseInt(servletContext.getInitParameter("minFoo")).intValue();

    }

    @GET
    @Path("/thing")
    public void foo() {
        System.out.println("in wizard service " + context); // available here
        System.out.println("minFoo " + minFoo); 
    }
}

This will allow you to perform additional initialization with the servletContext available.

Obvious note - you don't have to use the method name setServletContext. You can use any method name you want so long as you follow the standard java bean naming pattern for setters, void setXXX(Foo foo) and use the @Context annotation.

Interpolation answered 6/1, 2013 at 15:15 Comment(1)
shouldn't it be setServletContext (@Context ServletContext context)Outman
R
6

The servlet context is also available when you implement the ServletContextListener. This makes it easy to load parameters such as connection string at start-up. You can define the listener class in web.xml that loads you ServletContextListener at startup of your web application.

Inside the web.xml file, add the <listener>and <context-param> tags. The <listener> specifies the class that is called at startup. The <context-param> tag defines context parameter that is available within your web application.

First, include the <listener>and <context-param> tags in the web.xml file:

<web-app>
  <!-- ... -->
  <listener>
    <listener-class>com.your.package.ServletContextClass</listener-class>
  </listener>

  <!-- Init parameters for db connection -->
  <context-param>
    <param-name>your_param</param-name>
    <param-value>your_param_value</param-value>
  </context-param>
  <!-- ... -->
</web-app>

Now create the servlet context class as follows.

public class ServletContextClass implements ServletContextListener
{
  public void contextInitialized(ServletContextEvent arg0) 
   {
    //use the ServletContextEvent argument to access the 
    //parameter from the context-param
    String my_param = arg0.getServletContext().getInitParameter("your_param");
   }//end contextInitialized method

  @Override
  public void contextDestroyed(ServletContextEvent arg0) 
  { }//end constextDestroyed method
}

You can now choose which static variable to assign the parameter you have read. This allows you to read the parameter once at start-up, and reuse many time through the static variable that you assign it to.

Reaves answered 9/4, 2015 at 11:25 Comment(1)
It's also possible to place the context-params in conf/context.xml in Apache Tomcat: https://mcmap.net/q/297056/-defining-tomcat-servlet-context-parametersHabitat
A
5

Just use resource injection like this,

@Resource ServletContext servletContext;
African answered 29/11, 2009 at 4:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.