在Application中获取ServletContext

你能解释一下如何在我的Application的子类中获取ServletContext实例吗? 可能吗? 我试着像在下面的代码片段中那样做,但似乎没有用 – 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; } } 

web.xml中:

   environment development   jersey-filter org.glassfish.jersey.servlet.ServletContainer  javax.ws.rs.Application my.MainApplication   ...  

问题是我需要从中获取上下文参数。 如果有另一种方式,如果有人提示,我将不胜感激。


我理解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 getSingletons() { Set set = new HashSet(); 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; } } 

谢谢。

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

 public class MyApplication extends ResourceConfig { public MyApplication(@Context ServletContext servletContext) { // TODO } } 

通过使用@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. } } // ... 

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

对于类com.sun.jersey.spi.container.servlet.ServletContainer ,泽西岛版本1.18的文档中有一个有趣的声明。

servlet或filter可以配置为具有初始化参数“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的适当部分:

  Jersey Web Application com.sun.jersey.spi.container.servlet.ServletContainer  javax.ws.rs.Application experiment.service.ExampleApplication   

但不知何故,我失败了以下消息:

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

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

您可以使用ApplicationEventListener接口来获取ServletContext 。 初始化完成后,您可以“捕获” ApplicationEvent并使用注入的ServletContext进行操作。

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

泽西岛文件 – 20.1.2。 事件听众

您的MainApplication

 @ApplicationPath("/") public class MainApplication extends Application { @Override public Set> getClasses() { Set> set = new HashSet>(); 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; } } 

不要在Application使用@Context ,而是在Resource类中使用。

 @Path("/foos") public class FooResource { @Context ServletContext ctx; @GET public Response getFoos() { return Response.ok().build(); } }