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