您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

通过postValidate进行JSF跨字段验证,而无需在后备bean中按名称查找组件

通过postValidate进行JSF跨字段验证,而无需在后备bean中按名称查找组件

可以做到的。在下面的代码中,特别注意postValidate复合组件中的事件和postValidate后备组件中的方法。请注意,它如何解析MethodExpression属性调用传入的方法

这是复合组件:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <!-- Login form. -->
    <cc:interface componentType="com.example.LoginForm">
        <cc:attribute name="emailAddress" type="java.lang.String" required="true"/>
        <cc:attribute name="rememberMe" type="java.lang.Boolean" required="true"/>
        <cc:attribute name="checkCredentials"
                      method-signature="void checkCredentials(java.lang.String,java.lang.String,java.lang.String)"
                      shortDescription="Parameters are clientId, username and password. If credentials are invalid, attach a FacesMessage to the component specified by clientId."
                      required="true"/>
        <cc:attribute name="actionListener" method-signature="void actionListener()" required="true"/>
        <cc:attribute name="registerOutcome" type="java.lang.String" required="true"/>
        <cc:attribute name="recoverPasswordOutcome" type="java.lang.String" required="true"/>
        <cc:attribute name="headerTitle" type="java.lang.String" default="Sign In"/>
        <cc:attribute name="emailAddressLabel" type="java.lang.String" default="Email address:"/>
        <cc:attribute name="passwordLabel" type="java.lang.String" default="Password:"/>
        <cc:attribute name="rememberMeLabel" type="java.lang.String" default="Stay signed in on this machine"/>
        <cc:attribute name="loginLabel" type="java.lang.String" default="Sign In"/>
        <cc:attribute name="recoverPasswordLabel" type="java.lang.String" default="Forgot password?"/>
        <cc:attribute name="emailAddressrequiredMessage" type="java.lang.String" default="Email address required"/>
        <cc:attribute name="passwordrequiredMessage" type="java.lang.String" default="Password required"/>
        <cc:attribute name="registerLabel" type="java.lang.String" default="Register"/>
    </cc:interface>

    <cc:implementation>
        <h:outputStylesheet library="components/example/login-form" name="style.css"/>

        <div id="#{cc.clientId}">
            <h:form id="form">

                <f:event type="postValidate" listener="#{cc.postValidate}"/>

                <div style="margin-top:10px;">
                    <p:panel header="#{cc.attrs.headerTitle}" styleClass="loginPanel">
                        <div class="login-form_errorContainer">
                            <p:messages rendered="#{facesContext.maximumSeverity.ordinal ge 2}"/>
                        </div>
                        <h:panelGrid columns="3">
                            <h:outputText styleClass="login-form_label" value="#{cc.attrs.emailAddressLabel}"/>
                            <h:panelGroup styleClass="login-form_cell">
                                <h:inputText id="emailAddress"
                                             value="#{cc.attrs.emailAddress}"
                                             required="true"
                                             requiredMessage="#{cc.attrs.emailAddressrequiredMessage}"
                                             styleClass="login-form_field"
                                             immediate="true"/>
                            </h:panelGroup>
                            <h:panelGroup/>

                            <h:outputText styleClass="login-form_label" value="#{cc.attrs.passwordLabel}"/>
                            <h:panelGroup styleClass="login-form_cell">
                                <h:inputSecret id="password"
                                               value="#{cc.attrs.password}"
                                               required="true"
                                               requiredMessage="#{cc.attrs.passwordrequiredMessage}"
                                               styleClass="login-form_field"
                                               immediate="true"/>
                            </h:panelGroup>
                            <h:link styleClass="login-form_link" value="#{cc.attrs.recoverPasswordLabel}" outcome="#{cc.attrs.recoverPasswordOutcome}"/>

                            <h:panelGroup/>
                            <p:selectBooleanCheck@R_571_2419@ value="#{cc.attrs.rememberMe}" itemLabel="#{cc.attrs.rememberMeLabel}" immediate="true"/>
                            <h:panelGroup/>

                            <h:panelGroup/>
                            <h:panelGroup>
                                <p:commandButton id="submitForm" value="#{cc.attrs.loginLabel}" actionListener="#{cc.attrs.actionListener}" update="form"/>
                                <span class="login-form_or">or</span>
                                <h:link styleClass="login-form_link" value="#{cc.attrs.registerLabel}" outcome="#{cc.attrs.registerOutcome}"/>
                            </h:panelGroup>
                            <h:panelGroup/>
                        </h:panelGrid>
                    </p:panel>
                </div>
            </h:form>
        </div>
    </cc:implementation>
</html>

支持组件:

@FacesComponent("com.example.LoginForm")
public class LoginFormComponent extends UIInput implements NamingContainer
{
    @Override
    protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) throws ConverterException
    {
        UIInput emailAddressComponent = (UIInput) findComponent(EMAIL_ADDRESS_ID);
        UIInput passwordComponent = (UIInput) findComponent(PASSWORD_ID);
        String emailAddress = (String) emailAddressComponent.getValue();
        String password = (String) passwordComponent.getValue();
        return new LoginFormValue(emailAddress, password);
    }

    public void postValidate(ComponentSystemEvent e) {
        FacesContext ctx = getFacesContext();

        // Don't validate credentials if the username and/or password fields are invalid.
        if (!ctx.getMessageList(EMAIL_ADDRESS_ID).isEmpty() || !ctx.getMessageList(PASSWORD_ID).isEmpty())
        {
            return;
        }

        LoginFormValue value = (LoginFormValue) getConvertedValue(null, null);
        MethodExpression checkCredentials = (MethodExpression) getAttributes().get(CHECK_CREDENTIALS_ATTRIBUTE_NAME);
        checkCredentials.invoke(ctx.getELContext(), new Object[]{getClientId(), value.getEmailAddress(), value.getpassword()});
    }

    @Override
    public String getFamily()
    {
        return "javax.faces.NamingContainer";
    }

    public static final String CHECK_CREDENTIALS_ATTRIBUTE_NAME = "checkCredentials";
    public static final String EMAIL_ADDRESS_ID = "form:emailAddress";
    public static final String PASSWORD_ID = "form:password";
}

LoginFormValue物品是否完整类:

public class LoginFormValue
{
    public LoginFormValue(String emailAddress, String password)
    {
        this.emailAddress = emailAddress;
        this.password = password;
    }

    public String getEmailAddress()
    {
        return emailAddress;
    }

    public String getpassword()
    {
        return password;
    }

    private String emailAddress;
    private String password;
}

使用登录表单的页面

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ex="http://java.sun.com/jsf/composite/components/example">
    <h:head>
        <title></title>
    </h:head>
    <h:body>
        <ui:composition template="/WEB-INF/templates/myLayout.xhtml">
            <ui:define name="windowTitle">Sign In</ui:define>
            <ui:define name="body">

                <ex:login-form emailAddress="#{loginBean.emailAddress}"
                               rememberMe="#{loginBean.rememberMe}"
                               checkCredentials="#{loginBean.checkCredentials}"
                               actionListener="#{loginBean.submit()}"
                               recoverPasswordOutcome="recover-password"
                               registerOutcome="signup"/>

            </ui:define>
        </ui:composition>
    </h:body>
</html>

最后,页面支持者:

@Named
@RequestScoped
public class LoginBean implements Serializable
{
    public String getEmailAddress()
    {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress)
    {
        this.emailAddress = emailAddress;
    }

    public boolean isRememberMe()
    {
        return rememberMe;
    }

    public void setRememberMe(boolean rememberMe)
    {
        this.rememberMe = rememberMe;
    }

    /** Action listener for login-form. Called after validation passes. */
    public void submit()
    {
        User user = userDao.findByEmailAddress(emailAddress);
        userRequestBean.login(user.getUserId());

        // Remember me
        if (!rememberMe)
        {
            return;
        }

        // Handle rememberMe here (create a cookie, etc.)
    }

    /** Called by the backing component's postValidate event handler */
    public void checkCredentials(String clientId, String emailAddress, String password)
    {
        if (!securityEjb.checkCredentials(emailAddress, password))
        {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Incorrect email address/password", null);
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(clientId, message);
            ctx.renderResponse();
        }
    }

    private String emailAddress = "";

    private boolean rememberMe = true;

    @Inject
    private UserRequestBean userRequestBean;

    @EJB
    private SecurityEjb securityEjb;

    @EJB
    private UserDao userDao;

    @EJB
    private LoginCookieDao loginCookieDao;
}
其他 2022/1/1 18:32:42 有413人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶