1

제가 아는 한, CDI는 필터에서 작동해야하지만, 저를 위해 작동 할 수는 없습니다. 코드는 다음과 같습니다@Inject in filter가 작동하지 않습니다.

@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 (를 통해 수동으로 그것을 할 경우 작동) 또는 서블릿에서 :

@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가 작동하지 않습니까? 그렇다면 왜 안 되니? 그것이해야한다면, 나는 무엇을 잘못하고있을 수 있습니까?

+0

어떤 컨테이너입니까? JBoss AS 6는 매우 비슷한 버그가 있습니다. '@ EJB' 만 사용하면 제대로 작동합니까? – BalusC

+0

JBoss AS 6 실제로 ... @EJB가 아마 작동 할 것입니다. 매우 성가신, 난 그냥 수동으로 끝에 InitialContext 통해 주입했지만 좋은 이유를 알고 있습니다. –

답변

3

이 예제에서는 CODI @ViewAccessScoped 빈 (RegisterView)을 필터에 삽입하고 빈에서 속성을 설정 한 다음 해당 빈을 사용하는보기로 이동합니다. 페이지가로드되면 사용자 이름이 "fred"로 표시됩니다. @SessionScoped에서도 작동합니다 (단, @RequestScoped 또는 @ViewScoped는 해당하지 않습니다). 웹 컨테이너에는 필터 인스턴스가 하나 뿐이므로 모든 인스턴스 변수가 있기 때문에 동적 인젝션이 스레드 안전성에 필요하다고 생각합니다.

이 문제는 필터가 실행될 때 Faces Servlet이 실행되지 않아서 FacesContext가없는 문제가 해결되었습니다. getFacesContext()에 의해 수행 된 영리한 작업은 2004 년부터이 blog에서 곧바로 해제되었습니다. 누가 작성했는지 모르며 몇 년 동안 추가 된 내용이 없습니다. 아무도 알려주지 않으면 알 수 있습니다. 아마도 어린 시절의 에서 BalusC 였을 것입니다. 정적 인 내부 클래스를 사용하여 보호 된 FacesServlet # setCurrentInstance() 메소드에 액세스합니다.

response.sendRedirect()를 사용하면 작동하지 않습니다.

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; 
    } 

} 
관련 문제