我正在将JAX-RS应用程序部署到JBoss EAP 6.2。
我试图从JAX-RS资源类的内部获取一个ServletContext
,以便我可以读取在context-param
文件中设置的一些WEB-INF/web.xml
值。
即,在掌握了ServletContext
之后,我打算调用ServletContext#getInitParam
以获得值。
我正在使用注入方法按照建议here的方式获取ServletContext
。
我的web.xml
的相关部分是:
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>foo.MyApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/jax-rs/*</url-pattern>
</servlet-mapping>
所以我正在使用与JBoss捆绑在一起的RESTEasy。
类
MyApplication
是:public class MyApplication extends Application {
private Set<Object> singletons = new HashSet<>();
public MyApplication() {
singletons.add( new MyResource() );
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
…最后在
MyResource
类中,我有以下内容:@Path(...)
public class MyResource {
@Context
ServletContext context;
public MyResource() {
// I understand context is supposed to be null here
}
// ... but it should have been injected by the time we reach the service method.
@Path("/somePath")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response someMethod( ) {
if (context==null) throw new RuntimeException();
...
}
}
上面的代码始终导致抛出
RuntimeException
。即RESTEasy某种程度上无法注入ServletContext
。请注意,我没有任何其他JAX-RS问题。即如果我对希望通过ServletContext#getInitParameter检索的context-param
值进行硬编码,那么将WAR部署到JBoss时,JAX-RS rest功能将按预期工作。进一步实验发现,只有在对服务方法的参数执行注入时,才会注入
ServletContext
,如下所示:@Path("/somePath")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response someMethod(@Context ServletContext servletContext) {
...
}
…但是我不希望更改API。而且,我想一劳永逸地根据
context-param
值执行一些昂贵的初始化,而不是每次服务方法调用时都要执行。我的问题是:
为什么注射失败?
我对注释魔术在运行时失败感到有些厌倦,有没有一种方法可以在不使用注释的情况下获取
ServletContext
?或者,我的
MyApplication
类是否可以获取ServletContext
并将其作为构造函数参数传递给MyResource
类?如果所有其他方法都失败了,我想我总是可以使用
Class#getResourceAsStream
自己读取和解析web.xml文件吗? 最佳答案
根据链接到this answer的FrAn的评论,这就是我最终要做的事情:
public class JaxRsApplication extends Application {
private Set<Object> singletons = new HashSet<>();
public JaxRsApplication(@Context ServletContext servletContext) {
Assert.assertNotNull(servletContext);
singletons.add( new UserDatabaseResource(servletContext) );
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
…然后在
UserDatabaseResource
类中,我有以下内容:public UserDatabaseResource(ServletContext servletContext) {
Assert.assertNotNull(servletContext);
...
String jndiNameForDatasource = servletContext.getInitParameter("whatever")) ;
...
}
这作为
UserDatabaseResource
类工作,这是我的DAL层是单例的,我只需要获取要使用的数据源的JNDI名称(来自web.xml
文件)。但是也许这种方法也可以对非单身人士的班级进行一些小的调整。关于java - @Context未在RESTEasy JAX-RS应用程序中注入(inject)ServletContext,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41990590/