是否可以在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过滤器中使用Login
bean,但它总是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
。
我的要求是管理用户会话并实现记住我的功能。所以,要做到这一点,我首先在loginController
创建cookie / s,然后才有效。
在这里,通过上述设置 - 首先我想避免不必要的会话创建。我想要登陆登录页面,但没有会话。这个要求是所有这些过滤器和相关的重新/工作背后的驱动力。我求助于<c:view transient="true">
。我不确定,有效与否。现在,在你的一个答案中,你在支持bean中写了we should not put cookie and other authorization and authentication
相关内容。
所以,我对自己说 - 好吧,我没有在我的代码中遵循良好的做法,为什么不写一个过滤器,如果我可以拦截那里的Login
bean我应该能够执行我的身份验证/授权和cookie相关的东西本身。通过这种方式,我可以避免点击view scoped loginController
而不会发生不需要的会话。我可以通过编程方式控制会话。这从来没有奏效,所以这就是我问这个问题的原因。
在你的一个答案中,你写了 - session creation is cheap
- 但我仍然希望在访问我的应用程序的login page
时避免使用它。
现在,我最终完成并工作的是 - 我的登录表单使用普通的html输入字段然后在登录操作中我以旧的servlet方式拦截这些字段值。对于有效的尝试 - 我创建了一个会话programmatically
并重定向。
如果我能改进,请告诉我。