Dependency injection @注入过滤器不';行不通

Dependency injection @注入过滤器不';行不通,dependency-injection,java-ee-6,servlet-filters,cdi,jboss-weld,Dependency Injection,Java Ee 6,Servlet Filters,Cdi,Jboss Weld,据我所知,CDI应该在过滤器中工作,但我不能让它为我工作。代码如下所示: @WebFilter(filterName="authFilter",servletNames={"Faces Servlet"}) public class AuthFilter implements Filter { @Inject UserBean userBean; public AuthFilter() { } @Override public void doFilt

据我所知,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());
}

CDI在过滤器中不起作用吗?既然如此,为什么不呢?如果应该,我可能做错了什么?

在本例中,我将一个CODI@ViewAccessScope bean(RegisterView)注入过滤器,在bean中设置一个属性,并导航到使用该bean的视图。当页面加载时,我看到用户名设置为“fred”。这也适用于@SessionScoped(但不适用于@RequestScoped或@ViewScoped)。我认为线程安全需要动态注入,因为web容器中只有一个过滤器实例,因此所有实例变量都是如此

这个解决的问题是当过滤器执行时FacesServlet没有运行,因此没有FacesContext。getFacesContext()所做的聪明工作是我从2004年起直接从这本书中摘取的,我不知道这本书是谁写的,多年来一直没有添加任何内容,但是如果有人知道,请告诉我!也许是巴卢斯克在他的房间里 年轻的日子。它使用静态内部类访问受保护的FacesServlet#setCurrentInstance()方法

如果使用response.sendRedirect(),则它不起作用

包uk.co.myco.jsfbeans.helper;
导入java.io.IOException;
导入javax.enterprise.inject.Instance;
导入javax.faces.FactoryFinder;
导入javax.faces.component.UIViewRoot;
导入javax.faces.context.FacesContext;
导入javax.faces.context.FacesContextFactory;
导入javax.faces.lifecycle.lifecycle;
导入javax.faces.lifecycle.LifecycleFactory;
导入javax.inject.inject;
导入javax.servlet.DispatcherType;
导入javax.servlet.Filter;
导入javax.servlet.FilterChain;
导入javax.servlet.FilterConfig;
导入javax.servlet.ServletContext;
导入javax.servlet.ServletException;
导入javax.servlet.ServletRequest;
导入javax.servlet.ServletResponse;
导入javax.servlet.annotation.WebFilter;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入uk.co.sportquest.entities.User;
import uk.co.sportquest.general.BaseClass;
导入uk.co.sportquest.general.Log;
导入uk.co.sportquest.jsfbeans.RegisterView;
/*
*@作者布伦丹·希利
* 
* http://www.thoughtsabout.net/blog/archives/000033.html
* 
*/
@WebFilter(filterName=“SocialAuthFilter”,urlPatterns={”/pages/SocialAuthFilter.xhtml},
dispatcherTypes={DispatcherType.FORWARD,DispatcherType.ERROR,DispatcherType.REQUEST,DispatcherType.INCLUDE})
公共类SocialAuthFilter扩展基类实现筛选器{
@注入
私有实例动态;
私有ServletContext ServletContext;
@凌驾
public void init(FilterConfig FilterConfig)抛出ServletException{
servletContext=filterConfig.getServletContext();
}
@凌驾
public void doFilter(ServletRequest-req、ServletResponse-res、FilterChain-chain)抛出IOException、ServletException{
HttpServletRequest请求=(HttpServletRequest)请求;
HttpServletResponse=(HttpServletResponse)res;
Log.Log(“testFilter:+request.getPathInfo());
FacesContext ctx=getFacesContext(请求、回复);
注册视图注册视图;
registerView=rvDynamic.get();
用户=新用户();
user.setUserName(“fred”);
registerView.setInputUser(用户);
FacesContext.getCurrentInstance().getExternalContext().redirect(“/pages/register.xhtml”);
}
@凌驾
公共空间销毁(){
}
私有抽象静态类InnerFacesContext扩展了FacesContext{
受保护的静态无效setFacesContextAsCurrentInstance(FacesContext FacesContext){
setCurrentInstance(FacesContext);
}
}
专用FacesContext getFacesContext(ServletRequest请求,ServletResponse响应){
//试着先得到它
FacesContext FacesContext=FacesContext.getCurrentInstance();
if(facesContext!=null){
返回面上下文;
}
FacesContextFactory contextFactory=(FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES\u CONTEXT\u FACTORY);
LifecycleFactory LifecycleFactory=(LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE\u FACTORY);
Lifecycle Lifecycle=lifecycleFactory.getLifecycle(lifecycleFactory.DEFAULT\u Lifecycle);
//设置私有成员servletContext=filterConfig.getServletContext();
//在中,您可以使用filter init()方法,或在此处按如下方式进行设置:
//ServletContext ServletContext=((HttpServletRequest)请求).getSession().getServletContext();
//请注意,如果您使用的是http以外的任何其他协议,则上述行将失败
//不将此实例设置为FacesContext.getCurrentInstance的当前实例
facesContext=contextFactory.getFacesContext(servletContext、请求、响应、生命周期);
//使用我们的内部类设置
setFacesContextAsCurrentInstance(facesContext);
//设置一个新的viewRoot,否则context.getViewRoot将返回null
UIViewRoot视图=facesContext.getApplication().getViewHandler().createView(facesContext,“”);
facesContext.setViewRoot(视图);
返回面上下文;
}
}

什么容器?JBossAS6有一个非常相似的错误。如果您只使用
@EJB
,它能工作吗?JBossAS6确实@EJB可能会工作。非常烦人,最后我只是通过InitialContext进行了手动注入,但很高兴知道原因。
package uk.co.myco.jsfbeans.helper;

import java.io.IOException;
import javax.enterprise.inject.Instance;
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.inject.Inject;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import uk.co.sportquest.entities.User;
import uk.co.sportquest.general.BaseClass;
import uk.co.sportquest.general.Log;
import uk.co.sportquest.jsfbeans.RegisterView;

/*
 * @author Brendan Healey
 * 
 * http://www.thoughtsabout.net/blog/archives/000033.html
 * 
 */

@WebFilter(filterName = "SocialAuthFilter", urlPatterns = {"/pages/socialAuthFilter.xhtml"},
dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.ERROR, DispatcherType.REQUEST, DispatcherType.INCLUDE})
public class SocialAuthFilter extends BaseClass implements Filter {

    @Inject
    private Instance<RegisterView> rvDynamic;

    private ServletContext servletContext;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        servletContext = filterConfig.getServletContext();
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        Log.log("testFilter: " + request.getPathInfo());

        FacesContext ctx = getFacesContext(req, res);

        RegisterView registerView;
        registerView = rvDynamic.get();

        User user = new User();
        user.setUserName("fred");
        registerView.setInputUser(user);

        FacesContext.getCurrentInstance().getExternalContext().redirect("/pages/register.xhtml");

    }

    @Override
    public void destroy() {
    }

    private abstract static class InnerFacesContext extends FacesContext {

        protected static void setFacesContextAsCurrentInstance(FacesContext facesContext) {
            FacesContext.setCurrentInstance(facesContext);
        }
    }

    private FacesContext getFacesContext(ServletRequest request, ServletResponse response) {
        // Try to get it first  
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext != null) {
            return facesContext;
        }

        FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
        LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
        Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

        // Either set a private member servletContext = filterConfig.getServletContext(); 
        // in you filter init() method or set it here like this:
        // ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
        // Note that the above line would fail if you are using any other protocol than http

        // Doesn't set this instance as the current instance of FacesContext.getCurrentInstance 
        facesContext = contextFactory.getFacesContext(servletContext, request, response, lifecycle);

        // Set using our inner class
        InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);

        // set a new viewRoot, otherwise context.getViewRoot returns null
        UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "");
        facesContext.setViewRoot(view);

        return facesContext;
    }

}