18

你能解释一下我如何在我的子类中获取ServletContext实例吗?Application可能吗?我试图像下面的代码片段那样做,但它似乎不起作用 -ctx没有设置:

import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;

//...

@ApplicationPath("/")
public class MainApplication extends Application {

    @Context ServletContext ctx;

    @Override
    public Set<Class<?>> getClasses() {     
        Set<Class<?>> classes = new HashSet<Class<?>>();
//...
        return classes;
    }
}

网页.xml:

<web-app ...>
 <context-param>
  <param-name>environment</param-name>
  <param-value>development</param-value>
 </context-param>
 <filter>
  <filter-name>jersey-filter</filter-name>
  <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
   <init-param>
   <param-name>javax.ws.rs.Application</param-name>
   <param-value>my.MainApplication</param-value>
  </init-param>
</filter>
...
</web-app>

问题是我需要从中获取上下文参数。如果有其他方法,如果有人给出提示,我将不胜感激。


我知道Context注释可能不是为此目的。其实,我不需要ServletContext自己。如果我能从 web.xml 获得上下文参数,我会非常高兴。

这是我真正需要的一个例子:

import java.util.HashSet;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;

import org.glassfish.hk2.utilities.binding.AbstractBinder;

public class MainApplication extends Application {

    @Context ServletContext ctx;

    @Override
    public Set<Object> getSingletons() {
        Set<Object> set = new HashSet<Object>();
        final String environment = ctx.getInitParameter("environment");
        //final String environment = ... get context parameter from web xml
        set.add(new AbstractBinder() {

            @Override
            protected void configure() {
                bind(new BaseDataAccess(environment)).to(DataAccess.class);             
            }
        });
        //...
        return set;
    }
}

谢谢。

4

6 回答 6

17

从 Jersey 2.5 开始,ServletContext 可以直接在构造函数中注入: https ://java.net/jira/browse/JERSEY-2184

public class MyApplication extends ResourceConfig {
    public MyApplication(@Context ServletContext servletContext) {
       // TODO
    }
}
于 2015-01-05T18:35:08.487 回答
2

@Context可以ResoureConfig通过使用@Context. 访问它的另一种方法是通过事件处理程序

试试下面的代码。

@ApplicationPath("...")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        register(StartupHandler.class);
    }

    private static class StartupHandler extends  AbstractContainerLifecycleListener {
        @Context
        ServletContext ctx;

        @Override
        public void onStartup(Container container) {
            // You can put code here for initialization. 
        }
    }
// ...
于 2014-10-30T07:07:39.283 回答
1

com.sun.jersey.spi.container.servlet.ServletContainer类的 Jersey 版本 1.18 的文档中有一个有趣的声明

servlet 或过滤器可以配置为具有初始化参数“com.sun.jersey.config.property.resourceConfigClass”或“javax.ws.rs.Application”,其值是实现 ResourceConfig 或应用。如果具体类有一个构造函数,该构造函数采用 Map 类型的单个参数,则使用该构造函数实例化该类,并将包含所有初始化参数的 Map 实例作为参数传递。

如果我的理解是正确的,则必须使用“包含所有初始化参数的 Map 实例”调用以下构造函数

public class ExampleApplication extends Application {
    public ExampleApplication(Map initParams) {
    }
    ...
}

这是 web.xml 的适当部分:

<servlet>
  <servlet-name>Jersey Web Application</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
       <param-name>javax.ws.rs.Application</param-name>
       <param-value>experiment.service.ExampleApplication</param-value>
    </init-param>
</servlet>

但不知何故,它对我来说失败了以下消息:

严重:在参数索引 0 处缺少构造函数 public Experiment.service.ExampleApplication(java.util.Map) 的依赖项

对于当前版本的泽西岛(2.5.1),文档中没有这样的声明: https ://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/servlet/ServletContainer.html

于 2014-01-04T23:09:46.590 回答
1

输入服务方法时会发生注入。检查这是否有问题。

于 2013-10-18T12:59:12.533 回答
1

您可以使用该ApplicationEventListener接口获取ServletContext. 初始化完成后,您可以“捕获”ApplicationEvent并使用注入ServletContext来处理。

适用于:org.glassfish.jersey:2.12
对于其他版本,请使用评论 - 我不知道,对不起。

泽西文档 - 20.1.2。事件监听器

你的MainApplication

@ApplicationPath("/")
public class MainApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {     
        Set<Class<?>> set = new HashSet<Class<?>>();
        set.add(MainApplicationListener.class);
        return classes;
    }
}

...或替代方案MainResourceConfig(我更喜欢使用这个):

public class MainResourceConfig extends ResourceConfig {
    public MainResourceConfig() {
        register(MainApplicationListener.class);
    }
}

ApplicationEventListener

public class MainApplicationListener implements ApplicationEventListener {

    @Context
    private ServletContext ctx; //not null anymore :)

    @Override
    public void onEvent(ApplicationEvent event) {
        switch (event.getType()) {
            case INITIALIZATION_FINISHED:
            // do whatever you want with your ServletContext ctx
            break;
    }

    @Override
    public RequestEventListener onRequest(RequestEvent requestEvent) {
        return null;
    }

}
于 2014-09-11T17:52:56.287 回答
0

不要@Context在你的Application但在资源类中使用。

@Path("/foos")
public class FooResource {

  @Context
  ServletContext ctx;

  @GET
  public Response getFoos() {
    return Response.ok().build();
  }
}
于 2013-10-18T12:59:56.993 回答