在servlet过滤器中注入CDI bean中的Access FacesContext

问题描述 投票:0回答:1

我在注入CDI bean的地方有以下servlet

public class FBOAuthFilter implements Filter {
    @Inject 
    private Instance<LoginBean> loginBeanSource;


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain fc) throws IOException, ServletException {
        try{
           String code = request.getParameter("code");
           LoginBean loginBean = loginBeanSource.get();
           loginBean.doLogin(code);
        } catch(Exception ex){
           System.out.println("Exception");
        }
   }
}

CDI Bean:

@Named(value="loginbean")
@SessionScoped
public class LoginBean implements Serializable{



     public void doLogin(String code){
        //do something

        FacesContext context = FacesContext.getCurrentInstance();
        System.out.println(context == null);
        context.getExternalContext().redirect("somepage");

    }
}

但是,当我尝试访问CDI Bean中的FacesContext时,其为null。有没有办法访问FacesContext?

jsf servlets cdi servlet-filters
1个回答
0
投票

这不是正确的方法。

所有过滤器运行之前命中servlet。仅当击中FacesContext时,FacesServlet才可用。因此,只要FacesServlet尚未命中,就FacesContext尚不可用。因此,在所有过滤器中始终为null

您需要以这样的方式重写代码,即您可以仅使用过滤器中易于使用的requestresponse对象以及CDI,而无需依赖FacesContext。看来您只想执行重定向。 “普通香草” servlet方式是:

response.sendRedirect("somepage");

为了正确使用它,只需将您的LoginBean代码拆分为两个新的bean:一个在任何地方都不使用javax.faces.*东西,另一个则需要javax.faces.*东西。然后,过滤器和托管Bean都可以共享不在任何地方使用javax.faces.*的东西。

@Dependent
public class LoginBeanWithoutFacesContext implements Serializable {

    public void doLogin(String code) {
        // do something without faces context
    }
}

@Named
@SessionScoped
public class LoginBean implements Serializable {

     @Inject
     private LoginBeanWithoutFacesContext loginBeanWithoutFacesContext;

     public void doLogin(String code) {
         loginBeanWithoutFacesContext.doLogin(code);

         FacesContext context = FacesContext.getCurrentInstance();
         context.getExternalContext().redirect("somepage");
    }
}

最后在过滤器中使用LoginBeanWithoutFacesContext

public class FBOAuthFilter implements Filter {

    @Inject 
    private LoginBeanWithoutFacesContext loginBeanWithoutFacesContext;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            String code = request.getParameter("code");
            loginBeanWithoutFacesContext.doLogin(code);
            response.sendRedirect("somepage");
        }
        catch(Exception e){
            throw new ServletException(e);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.