Java 在应用程序中获取 ServletContext
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19450202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get ServletContext in Application
提问by Industrious
Could you possibly explain how I can get the ServletContext
instance in my Application
's sub-class? Is it possible? I have tried to do it like in the following snippet but it does not seem to work - the ctx
is not set:
你能解释一下我如何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:
网页.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>
The problem is that I need to get context parameters from it. If there is another way, I would be grateful if somebody gave a hint.
问题是我需要从中获取上下文参数。如果有另一种方式,如果有人给出提示,我将不胜感激。
I understand that Context
annotation might not be purposed for this. Actually, I do not need ServletContext
itself. If only I could get context params from web.xml, I would be absolutely happy.
我知道Context
注释可能不是用于此目的。其实,我不需要ServletContext
自己。如果我能从 web.xml 获取上下文参数,我会非常高兴。
Here is an example of what I really need:
这是我真正需要的一个例子:
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;
}
}
Thanks.
谢谢。
采纳答案by Laurent Mazuel
Since Jersey 2.5, ServletContext can be injected directly in constructor: https://java.net/jira/browse/JERSEY-2184
从 Jersey 2.5 开始,ServletContext 可以直接注入到构造函数中:https: //java.net/jira/browse/JERSEY-2184
public class MyApplication extends ResourceConfig {
public MyApplication(@Context ServletContext servletContext) {
// TODO
}
}
回答by user987339
Injection happens when you enter service method. Check if this is a problem.
进入服务方法时会发生注入。检查这是否有问题。
回答by user987339
Don't use @Context
in your Application
but in a Resource class.
不要@Context
在您的Application
但在 Resource 类中使用。
@Path("/foos")
public class FooResource {
@Context
ServletContext ctx;
@GET
public Response getFoos() {
return Response.ok().build();
}
}
回答by Sergey Petrunin
There is interesting statement in documentation for Jersey version 1.18 for class com.sun.jersey.spi.container.servlet.ServletContainer
对于类com.sun.jersey.spi.container.servlet.ServletContainer 的Jersey 版本 1.18 的文档中有一个有趣的声明
The servlet or filter may be configured to have an initialization parameter "com.sun.jersey.config.property.resourceConfigClass" or "javax.ws.rs.Application" and whose value is a fully qualified name of a class that implements ResourceConfig or Application. If the concrete class has a constructor that takes a single parameter of the type Map then the class is instantiated with that constructor and an instance of Map that contains all the initialization parameters is passed as the parameter.
servlet 或过滤器可以配置为具有初始化参数“com.sun.jersey.config.property.resourceConfigClass”或“javax.ws.rs.Application”,其值是实现 ResourceConfig 或应用。如果具体类有一个构造函数,该构造函数采用 Map 类型的单个参数,则使用该构造函数实例化该类,并且包含所有初始化参数的 Map 实例作为参数传递。
If my understanding is correct the following constructor must be invoced with "an instance of Map that contains all the initialization parameters"
如果我的理解是正确的,则必须使用“包含所有初始化参数的 Map 实例”调用以下构造函数
public class ExampleApplication extends Application {
public ExampleApplication(Map initParams) {
}
...
}
Here is appropriate part of web.xml:
这是 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>
But somehow it failed for me with the following message:
但不知何故,我失败了,并显示以下消息:
SEVERE: Missing dependency for constructor public experiment.service.ExampleApplication(java.util.Map) at parameter index 0
严重:在参数索引 0 处缺少构造函数 publicexperiment.service.ExampleApplication(java.util.Map) 的依赖项
And for current version of Jersey (2.5.1) there are no such statement in documentstion: https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/servlet/ServletContainer.html
对于当前版本的 Jersey (2.5.1),文档中没有这样的声明:https: //jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/servlet/ServletContainer.html
回答by zyexal
You can use the ApplicationEventListener
interface to get the ServletContext
. After initialization has finished, you can 'catch' an ApplicationEvent
and use the injected ServletContext
to work with.
您可以使用该ApplicationEventListener
接口获取ServletContext
. 初始化完成后,您可以“捕获”ApplicationEvent
并使用注入的对象ServletContext
进行处理。
Works fine with: org.glassfish.jersey : 2.12
For additional versions, pls use comments - i dont know, sry.
适用于:org.glassfish.jersey : 2.12
对于其他版本,请使用注释 - 我不知道,对不起。
Jersey Docs - 20.1.2. Event Listeners
Your MainApplication
:
你的MainApplication
:
@ApplicationPath("/")
public class MainApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(MainApplicationListener.class);
return classes;
}
}
... or alternative MainResourceConfig
(I prefer to use this one):
...或替代方案MainResourceConfig
(我更喜欢使用这个):
public class MainResourceConfig extends ResourceConfig {
public MainResourceConfig() {
register(MainApplicationListener.class);
}
}
And the ApplicationEventListener
:
和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;
}
}
回答by Haruo Kinoshita
@Context
can be made available on ResoureConfig
by injecting it as a constructor parameter using @Context
. Another way to access it is through an event handler.
@Context
可以通过使用ResoureConfig
将其作为构造函数参数注入来使其可用@Context
。另一种访问它的方法是通过事件处理程序。
Try the below code.
试试下面的代码。
@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.
}
}
// ...