过滤器中的@Inject不起作用
据我所知,CDI 应该在过滤器中工作,但我无法让它为我工作。代码如下所示:
@WebFilter(filterName="authFilter",servletNames={"Faces Servlet"})
public class AuthFilter implements Filter {
@Inject UserBean userBean;
public AuthFilter() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
userBean.doSomething(); // Causes NullPointerException
chain.doFilter(request, response);
}
}
UserBean.class
@Stateless
public class UserBean extends JPABean{
// Omitted
}
CDI 已启用,如果我通过 InitialContext.doLookup() 或在 Servlet 中手动执行注入,则注入可以工作,如下所示:
@WebServlet(name = "MyServlet", urlPatterns = {"/MyPage"})
@ServletSecurity(@HttpConstraint(rolesAllowed={"somerole"}))
public class MyServlet extends HttpServlet {
@Inject private UserBean userBean;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
userBean.doStuff(); // Works
response.sendRedirect(request.getContextPath());
}
Do not CDI work in Filters?既然如此,为什么不呢?如果应该的话,我可能做错了什么?
As far as I know, CDI should work in filters, but I can't get it to work for me. Code looks like the following:
@WebFilter(filterName="authFilter",servletNames={"Faces Servlet"})
public class AuthFilter implements Filter {
@Inject UserBean userBean;
public AuthFilter() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
userBean.doSomething(); // Causes NullPointerException
chain.doFilter(request, response);
}
}
UserBean.class
@Stateless
public class UserBean extends JPABean{
// Omitted
}
CDI is enabled, and injection works if I do it in manually via InitialContext.doLookup() or in a Servlet, like this:
@WebServlet(name = "MyServlet", urlPatterns = {"/MyPage"})
@ServletSecurity(@HttpConstraint(rolesAllowed={"somerole"}))
public class MyServlet extends HttpServlet {
@Inject private UserBean userBean;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
userBean.doStuff(); // Works
response.sendRedirect(request.getContextPath());
}
Does not CDI work in Filters? In that case, why not? If it should, what could I possibly be doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在此示例中,我将 CODI @ViewAccessScoped bean (RegisterView) 注入到过滤器中,在 bean 中设置属性并导航到使用该 bean 的视图。当页面加载时,我看到用户名设置为“fred”。这也适用于@SessionScoped(但不适用于@RequestScoped或@ViewScoped)。我认为动态注入对于线程安全是必需的,因为 Web 容器中只有一个过滤器实例,因此所有实例变量也只有一个。
此方法解决的问题是,当过滤器执行时,Faces Servlet 尚未运行,因此没有 FacesContext。 getFacesContext() 所做的巧妙工作是我直接从 2004 年的博客中摘取的,我不知道是谁写的,而且已经好几年没有添加内容了,但如果有人知道请告诉我!也许是 BalusC 在他的
年轻的日子。它使用静态内部类来访问受保护的 FacesServlet#setCurrentInstance() 方法。
如果您使用response.sendRedirect(),它将不起作用。
In this example I inject a CODI @ViewAccessScoped bean (RegisterView) into a filter, set a property in the bean and navigate to a view which uses the bean. When the page loads I see the username set to "fred". This also works with @SessionScoped (but not @RequestScoped or @ViewScoped). I think dynamic injection is required for thread safety because there is only one instance of the filter in the web container and hence all instance variables.
The problem this is solving is that Faces Servlet hasn't run when the filter executes so there is no FacesContext. The clever work done by getFacesContext() I have lifted straight from this blog from 2004, I don't know who it was written by and there has been no content added for some years, but if anyone knows let me know! Maybe it was BalusC in his
younger days. It uses a static inner class to access the protected FacesServlet#setCurrentInstance() method.
It doesn't work if you use response.sendRedirect().