Is it possible to inject(CDI) request scoped bean in servlet filter?
My login.xhtml
as below -
<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>
On a POST
on this page, I need Login
bean in my servlet filter but it is always null
. My backing bean
@Named("login")
@RequestScoped
public class Login {
private String uname;//with getters and setters
private String upwd;
}
Below is how I'm injecting it in my filter -
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
}
Now working in the sense, the container injects a reference but all the fields are empty. I am expecting posted form data values i.e, values for the properties mentioned the the backing bean.
If its not possible, then is there any other way around? Intention is avoid session creation by using other types of scoped beans.
Update-
I did some changes as suggested in the comment section but still the values for the bean in question are 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.
}
What I thought of doing - I had a Login
request and LoginController
view scoped bean. This is how I started initially. So, for username and password Login
and loginController.login
on sign in action. This worked as expected. I was injecting Login
into LoginController
all field/s values were there.
My requirement was to manage user sessions and implement remember me functionality too. So, to do that I started by creating cookie/s in the loginController
and it worked.
Here, with the above setup - first I wanted to avoid unnecessary session creation. I wanted request to land on the login page but without a session. This requirement is the driving force behind all this filter/s and related re/work. I resorted to <c:view transient="true">
. This I'm not sure, worked or not. Now, in one of your answers you wrote that we should not put cookie and other authorization and authentication
related stuff inside backing beans.
So, I said to my myself - Okay, I'm not following good practice in my code and why not write a filter and if I could intercept the Login
bean there I should be able to execute my authentication/ authorization and cookie related stuff there itself. This way, I can avoid hitting the view scoped loginController
and no unwanted session. I can control the session programmatically. This never worked and so that's why I asked this question.
In one of your answers, you wrote - session creation is cheap
- but I still wanted to avoid it when the login page
of my application is accessed.
Now, what I have finally done and working is - my login form uses plain html input fields and then on login action I intercept these field value in old servlet way. For a valid attempt - I create a session programmatically
and redirect.
Please, let me know if I can improve.