我有以下servlet注入CDI bean
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?
答案 0 :(得分:1)
这不是正确的方法。
所有过滤器在命中servlet之前 运行。 FacesContext
仅在命中FacesServlet
时可用。因此,只要FacesServlet
尚未被点击,FacesContext
都不可用。因此,在所有过滤器中始终为null
。
您需要以以下方式重写代码:仅使用过滤器中易于使用的request
和response
对象和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);
}
}
}
也就是说,考虑对您显然在LoginBeanWithoutFacesContext
中从事的工作使用JEE标准身份验证或完善的库,而不要使用某些本地认证。另请参见How to handle authentication/authorization with users in a database?