I'm having problem with adding message to FacesContext
from Spring component. Here is the senario:
AuthenticationFailureHandler
, AuthenticationSuccessHandler
), which is primefaces.I can't add message via:
@Component
public class LoginFailureHandler implements AuthenticationFailureHandler {
private static Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class);
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
logger.info("Login failed: " + httpServletRequest.getParameter("j_username"), e);
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login Error", e.getLocalizedMessage());
FacesContext.getCurrentInstance().addMessage(null, message);
httpServletResponse.sendRedirect("/timsgui/login.jsf?error=1");
}
}
Because this class is not in JSF lifecycle, FacesContext.getCurrentInstance()
returns null
. Here is my jsf page:
<body>
<p:growl id="growl" sticky="true" showDetail="true" life="3000" />
<h:form name="login" action="../j_spring_security_check" method="POST">
<h:panelGrid>
<h:outputLabel for="j_username" value="Username:"/>
<p:inputText id="j_username"/>
<h:outputLabel for="j_password" value="Password:"/>
<p:password id="j_password"/>
<!-- need CSRF protection which is enabled default after Spring 4-->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<p:commandButton value="Login" update="growl" type="submit"/>
</h:panelGrid>
</h:form>
I tried to inject FacesContext
into spring bean but it still returns null
:
@ManagedProperty("#{facesContext}")
Is there anyway that i can inject current FacesContext
to the Spring bean or any other ideas that i can add that global message from Spring Bean to FacesContext
without FacesContext.getCurrentInstance().addMessage()
?
Okay, i solved this. Thanks @M.Delinum and @Xtreme Biker for your suggestions. I injected message into HttpSession and get it from http scope. Here is final code:
@Component
public class LoginFailureHandler implements AuthenticationFailureHandler {
private static Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class);
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
logger.info("Login failed: " + httpServletRequest.getParameter("j_username"), e);
HttpSession session = httpServletRequest.getSession(false);
if (session != null) {
session.setAttribute("loginFailMessage", "Login is failed");
}
httpServletResponse.sendRedirect("/timsgui/login.jsf?error=true");
}
}
<h:outputText value="#{sessionScope['loginFailMessage']}" rendered="#{not empty sessionScope['loginFailMessage']}" styleClass="highlight"/>