你能否解释我如何在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;
}
}
的web.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;
}
}
感谢。
答案 0 :(得分:16)
从Jersey 2.5开始,ServletContext可以直接在构造函数中注入: https://java.net/jira/browse/JERSEY-2184
public class MyApplication extends ResourceConfig {
public MyApplication(@Context ServletContext servletContext) {
// TODO
}
}
答案 1 :(得分: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.
}
}
// ...
答案 2 :(得分:1)
输入服务方法时会发生注入。检查这是否有问题。
答案 3 :(得分:1)
泽西岛版本1.18的文档中有一个有趣的声明 com.sun.jersey.spi.container.servlet.ServletContainer
servlet或过滤器可以配置为具有初始化 参数“com.sun.jersey.config.property.resourceConfigClass”或 “javax.ws.rs.Application”,其值是完全限定名 实现ResourceConfig或Application的类。如果具体 class有一个构造函数,它接受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>
但不知何故,我失败了以下消息:
严重:缺少构造函数public的依赖项 参数中的experiment.service.ExampleApplication(java.util.Map) index 0
对于泽西岛的当前版本(2.5.1),文件中没有这样的陈述: https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/servlet/ServletContainer.html
答案 4 :(得分:1)
您可以使用ApplicationEventListener
界面获取ServletContext
。初始化完成后,您可以“捕获”ApplicationEvent
并使用注入的ServletContext
进行操作。
适用于: org.glassfish.jersey:2.12
对于其他版本,请使用评论 - 我不知道,sry。
Jersey Docs - 20.1.2. Event Listeners
您的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;
}
}
答案 5 :(得分:0)
请勿在{{1}}中使用@Context
,而应使用资源类。
Application