2

我开发了一个简单的登录表单,用于我的 JSF + PrimeFaces 页面:

<form action="j_security_check" method="post"> 
    <p:dialog modal="true" header="Login" widgetVar="loginDlg">
        <h:panelGrid columns="3" cellpadding="5">  
            <h:outputLabel for="j_username">Username:</h:outputLabel> 
            <h:inputText id="j_username" required="true" /> 
            <h:message for="j_username" /> 
            <h:outputLabel for="j_password">Password:</h:outputLabel> 
            <h:inputSecret id="j_password" required="true" /> 
            <h:message for="j_password" /> 
            <br /> 
            <h:commandButton value="Login" /> 
        </h:panelGrid>
    </p:dialog>                
</form> 

尝试使用空密码,但组件未捕获缺少的密码(这是必需的)h:message。我也转而p:commandButton认为问题可能出在按钮的 Ajax 行为中,但由于 PrimeFaces 抱怨 CommandButton 不在表单元素内,因此未呈现页面。容器抛出的异常是:

com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Access denied on empty password for user pippo

总结一下,我有两个问题:

  1. 为什么在提交表单之前丢失的密码不会产生消息?
  2. 如何捕获 LoginException 并在对话框中显示错误消息?
4

1 回答 1

6

j_security_check请求由 Web 容器处理,而不是由 JSF 。这就解释了这 required="true"行不通。仅当您在与命令按钮关联的操作方法中使用 JSF<h:form>和编程登录时,它才有效。HttpServletRequest#login()

您可以做的最好的事情是配置一个<form-error-page>指向web.xml<form-login-page>. 然后您可以检查请求是否已j_security_check自行转发,这意味着发生了登录错误。

<h:panelGroup rendered="#{requestScope['javax.servlet.forward.servlet_path'] == '/j_security_check'}">
    <h:outputText value="Unknown login, please try again" styleClass="error" />
</h:panelGroup>

使用它而不是<h:message>.

至于为什么<p:commandButton>抱怨没有表格只是因为你没有使用<h:form>.


与具体问题无关,那个<form>(或者<h:form>当你决定切换到程序登录时)可以更好地放置在 的主体中<p:dialog>,而不是外部。JS的<p:dialog>can 被重新定位到 body 的末尾,这将导致它不再是一个表单。

于 2012-04-29T04:30:34.817 回答