添加来自 Spring Bean 的 JSF 消息
Add JSF Message From Spring Bean
我在从 Spring 组件向 FacesContext
添加消息时遇到问题。这是 senario:
- 用户从 .xhtml 页面登录
- Spring 安全授权用户
- 如果用户 success/failed、return 从 Spring 管理的 class 发送到 UI 的消息(
AuthenticationFailureHandler
、AuthenticationSuccessHandler
), 即 primefaces.
我无法通过以下方式添加消息:
@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");
}
}
因为这个 class 不在 JSF 生命周期中,所以 FacesContext.getCurrentInstance()
returns null
。这是我的 jsf 页面:
<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>
我试图将 FacesContext
注入 spring bean 但它仍然 returns null
:
@ManagedProperty("#{facesContext}")
有没有我可以将当前 FacesContext
注入 Spring bean 或任何其他想法,我可以将来自 Spring Bean 的全局消息添加到 FacesContext
没有 FacesContext.getCurrentInstance().addMessage()
?
好的,我解决了这个问题。感谢@M.Delinum 和@Xtreme Biker 的建议。我将消息注入 HttpSession 并从 http 范围获取它。这是最终代码:
@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"/>
我在从 Spring 组件向 FacesContext
添加消息时遇到问题。这是 senario:
- 用户从 .xhtml 页面登录
- Spring 安全授权用户
- 如果用户 success/failed、return 从 Spring 管理的 class 发送到 UI 的消息(
AuthenticationFailureHandler
、AuthenticationSuccessHandler
), 即 primefaces.
我无法通过以下方式添加消息:
@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");
}
}
因为这个 class 不在 JSF 生命周期中,所以 FacesContext.getCurrentInstance()
returns null
。这是我的 jsf 页面:
<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>
我试图将 FacesContext
注入 spring bean 但它仍然 returns null
:
@ManagedProperty("#{facesContext}")
有没有我可以将当前 FacesContext
注入 Spring bean 或任何其他想法,我可以将来自 Spring Bean 的全局消息添加到 FacesContext
没有 FacesContext.getCurrentInstance().addMessage()
?
好的,我解决了这个问题。感谢@M.Delinum 和@Xtreme Biker 的建议。我将消息注入 HttpSession 并从 http 范围获取它。这是最终代码:
@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"/>