在JAX-RS资源中获取ServletContext


67

我在玩JAX-RS,在Tomcat上部署。基本上是:

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

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

}

有什么方法可以让我掌握ServletContextJAX-RS资源吗?

Answers:


100

此外,@Resource注释可能不起作用。尝试这个

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

直到您按下服务方法,注入才会发生

public class MyService {
    @Context ServletContext context;

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

    @GET
    @Path("/thing") {               
             print("in  wizard service " + context); // available here

我将哪个javax.ws.rs类用作servlet处理程序?
leeeroy

不能真的让您如此。您已经拥有一个处理HTTP GET请求的类。请详细说明Servlet处理程序的含义。干杯。
阿德·安萨里

Servlet容器需要Servlet来处理请求。com.sun.ws.rest.spi.container.servlet.ServletContainer负责处理请求并将其分配给我的注释类。您暗示我不应该使用com.sun。*类,那么我应该使用什么呢?
leeeroy

为什么不使用任何流行的servlet容器,如Jetty或Tomcat?
阿德·安萨里

1
正如问题所说,我正在使用Tomcat。Tomcat不会盲目识别我的jax-rs注释类。它将需要一个servlet来处理请求。与码头交易相同。
leeeroy

9

正如其他人指出的那样,可以在字段级别注入ServletContext。也可以在方法级别上注入它:

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); 
    }
}

这将允许您使用可用的ServletContext执行其他初始化。

明显的注意事项-您不必使用方法名称setServletContext。您可以使用任何想要的方法名称,只要您遵循用于setter的标准java bean命名模式,void setXXX(Foo foo)并使用@Context批注即可。


不应将其设置为setServletContext(@Context ServletContext context)
Thomas

6

当您实现ServletContextListener时,servlet上下文也可用。这样可以很容易在启动时加载诸如连接字符串之类的参数。您可以在web.xml中定义侦听器类,该类将在Web应用程序启动时加载ServletContextListener。

在web.xml文件中,添加<listener><context-param>标签。该<listener>规定被称为启动类。该<context-param>标签定义上下文参数就是你的Web应用程序中使用。

首先,在web.xml文件中包含<listener><context-param>标记:

<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>

现在,如下创建servlet上下文类。

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
}

现在,您可以选择哪个静态变量来分配已读取的参数。这使您可以在启动时读取一次参数,并通过分配给它的静态变量多次重复使用。


也可以将context-params放置conf/context.xml在Apache Tomcat中:stackoverflow.com/a/1626190/2639234
KeksArmee 2016年

5

像这样使用资源注入

@Resource ServletContext servletContext;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.