从 CDI 扩展访问 servlet 上下文参数
我正在尝试编写一个 CDI 扩展,它需要通过
访问 web.xml 中定义的上下文参数。我认为有两种方法可以做到这一点:
- 以某种方式获取 ServletContext 并调用 getInitParameter()
- 手动解析 web.xml
不幸的是,我需要两种解决方案的 ServletContext 并获取它似乎是不可能的。这里的问题是一些容器在创建 ServletContext 之前启动 CDI。即使 ServletContext 在 CDI 启动之前可用,似乎也无法从 CDI 扩展访问它。我尝试使用 ServletContextListener
将 ServletContext
存储在静态 ThreadLocal
中。这似乎工作正常,但它会造成内存泄漏,因为我无法可靠地清理 ThreadLocal
。
在回答之前还有两条评论:
- 使用其他方法来读取配置参数(例如使用 JNDI)对我来说是没有选择的,因为我正在尝试编写一个 CDI 扩展来与第 3 方框架集成。
- 我知道这个问题可能没有解决方案可以在环境/容器之间 100% 可移植。但如果我找到一个适用于大多数情况的解决方案,我会很高兴。
谢谢! :)
I'm trying to write a CDI extension that needs to access the context parameters defined in web.xml via <context-param>
. I think there are two ways of doing this:
- Somehow get the
ServletContext
and callgetInitParameter()
- Manually parse the
web.xml
Unfortunately I need the the ServletContext
for both solutions and getting it doesn't seem to be possible. The problem here is that some containers startup CDI before the ServletContext
is created. And even if the ServletContext
would be available before CDI starts up, there seems to be no way to access it from the CDI extension. I experimented with a ServletContextListener
that stores the ServletContext
in a static ThreadLocal
. This seems to work fine but it would create a memory leak as I'm unable to cleanup the ThreadLocal
reliably.
Two more comments before you answer:
- Using some other approach to read configuration parameters (like using JNDI) is no option for me as I'm trying to write a CDI extension for integrating with a 3rd party framework.
- I'm aware of the fact that there will be probably no soltion for this problem that is 100% portable between environments/containers. But I would be happy if I find a solution that works in most cases.
Thanks! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我尝试做一些类似的事情,在 JBoss 7.1 上与 CDI bean 共享上下文。虽然它对我不起作用,但我不确定是否是 JBoss7.1 的当前状态导致了问题,所以也许它对你有用?
我所做的是在启动时有一些东西可以访问
ServletContext
(在我的例子中是 JAX-RSApplication
,但可能是您的侦听器或 servlet)访问应用程序-scoped bean 并在其中设置 ServletContext 。为了连接到 CDI 的世界,我使用以下 URI 中的配方来创建 bean 实例:
http://docs.jboss .org/weld/reference/1.1.0.Final/en-US/html/extend.html#d0e4978
相关代码类似于:
然后您可以将其设置为bean 看起来像:
使用如下片段:
在启动代码中 然后,您应该能够在您想要的任何 CDI 构造中 @Inject 上下文...假设它是在您的 servlet init 或其他什么之后运行的。
例如:
我很好奇这是否适用于其他情况......
I tried to do something similar with sharing the context with CDI beans in general on JBoss 7.1. Although it didn't work for me, I'm not sure if it's the current state of JBoss7.1 that caused the problems, so perhaps it'll work for you?
What I did was have something on startup that has access to the
ServletContext
(in my case a JAX-RSApplication
, but probably a listener or servlet for you) access an application-scoped bean and set theServletContext
in it.To bridge to the world of CDI, I used the recipe from the following URI to create the bean instance:
http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/extend.html#d0e4978
The relevant code is something like:
which you could then set into a bean that looks like:
using a snippet like:
in your startup code. You should then be able to just
@Inject
the context in whatever CDI construct you want it in... assuming it is run after your servlet init or whatever.For example:
I'll be curious if this works in other situations...
不确定您正在使用什么容器,但看起来在 JBoss 中至少您可以 使用注释注入 ServletContext。这对您不起作用,还是我没有正确理解您的 CDI 扩展的性质?
编辑:啊。我从未使用过 CDI 实现,但是否可以创建一个
ServletContextListener
来生成 CDI 事件,并将ServletContext
作为事件属性之一。然后,您可以只侦听扩展中的事件并提取ServletContext
。Not sure what container you're using, but it looks like in JBoss at least you can just inject the ServletContext using an annotation. Would this not work for you, or am I not properly understanding the nature of your CDI extension?
EDIT: ah. I've never used the CDI implementation, but would it be possible to create a
ServletContextListener
that generated a CDI event with theServletContext
as one of the event properties. You could then just listen for the event in your extension and extract theServletContext
.正如您自己和 Femi 所注意到的,如果 ServletContext 不可用,您就无法从中获取任何内容(例如 init params)。
读取 web.xml 文件是可能的,但可以肯定它很疯狂并且不可移植,但您始终可以尝试在特定部署上执行此操作,您可以从 WEB-INF 此处
As you have noticed yourself and Femi commented if the ServletContext is not available there is no way you can get anything from it (like init params).
Reading web.xml file is possible but for sure it's crazy and won't be portable, but you can always try to do it on your specific deployment, you can get an example of reading smth from WEB-INF here