1

是否可以在 servlet 过滤器中注入(CDI)请求范围的 bean?

login.xhtml的如下 -

<h:form>
    <h:inputText id="uname" value="#{login.uname}" />
    <h:inputSecret id="pwd" value="#{login.upwd}" />
     <h:commandButton action="#{loginc.login}" value="Login"  />

</h:form>

POST此页面上,我的 servlet 过滤器中需要Loginbean,但它始终是null. 我的后盾

@Named("login")
@RequestScoped
public class Login {
    private String uname;//with getters and setters
    private String upwd;
}

以下是我将其注入过滤器的方式 -

public class LoginFilter implements Filter {
@Inject
private Login login;
...
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//System.out.println(((Login)request.getAttribute("login")).toString()); **Not Working**
System.out.println("login ->" + login);//not working
}

现在从某种意义上说,容器注入了一个引用,但所有字段都是空的。我期待发布的表单数据值,即支持 bean 中提到的属性的值。

如果不可能,那么还有其他方法吗?意图是通过使用其他类型的作用域 bean 来避免创建会话。

更新-

我按照评论部分的建议做了一些更改,但问题中的 bean 的值仍然是null

public class LoginFilter implements Filter {

@Inject
private BeanManager beanManager;


public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    findBean("login", req);
    chain.doFilter(req, res);
}

public void findBean(String beanName, ServletRequest req){
    FacesContext facesContext = FacesContext.getCurrentInstance();
    System.out.println(facesContext == null);//always true
    System.out.println(beanManager==null);//is not null

    Bean bean = beanManager.getBeans(beanName).iterator().next();
    CreationalContext ctx = beanManager.createCreationalContext(bean);
    Login loginBean = (Login) beanManager.getReference(bean, bean.getBeanClass(),ctx);
    System.out.println(loginBean);//prints null as value for properties for post request also.
}

我想做什么- 我有一个Login请求并LoginController查看范围 bean。这就是我最初的开始方式。因此,对于用户名和密码Login以及loginController.login登录操作。这按预期工作。我正在注入Login所有LoginController字段/ s 值。

我的要求是管理用户会话并实现记住我的功能。所以,为了做到这一点,我首先在其中创建了 cookie/s,loginController并且它起作用了。

在这里,通过上述设置 - 首先我想避免不必要的会话创建。我希望请求登陆登录页面但没有会话。这一要求是所有这些过滤器和相关返工背后的驱动力。我使出<c:view transient="true">。这我不确定,工作与否。现在,在您的一个答案中,您we should not put cookie and other authorization and authentication在支持 bean 中写了相关的内容。

所以,我对自己说 - 好吧,我没有在我的代码中遵循良好的做法,为什么不编写一个过滤器,如果我可以在那里拦截Loginbean,我应该能够在那里执行我的身份验证/授权和 cookie 相关的东西. 这样,我可以避免点击view scoped loginController并且没有不需要的会话。我可以以编程方式控制会话。这从来没有奏效,所以这就是我问这个问题的原因。

在您的一个答案中,您写道 -session creation is cheap但我仍然想在login page访问我的应用程序时避免它。

现在,我最终完成和工作的是 - 我的登录表单使用纯 html 输入字段,然后在登录操作中我以旧的 servlet 方式截取这些字段值。对于有效的尝试 - 我创建一个会话programmatically并重定向。

请让我知道我是否可以改进。

4

0 回答 0