如何在JSF

时间:2016-08-29 00:13:41

标签: jsf jsf-2

我有一个带有UNI约束的Name,当用户注册一个重复的名称时,它会引发异常:

Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'John' for key 'UK_t622yodh32su1s2wseebkimwp'

在JSF视图页面中,异常处理程序捕获的异常将显示给用户:

Duplicate entry 'John' for key 'UK_t622yodh32su1s2wseebkimwp'

代码:

public void register (Student student) {
   ...

catch (Exception e) {
            String errorMessage = getRootErrorMessage(e);
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Registration unsuccessful");
            facesContext.addMessage(null, m);
        }
}

private String getRootErrorMessage(Exception e) {

        String errorMessage = "Registration failed.";
        if (e == null) {
            return errorMessage;
        }

        Throwable t = e;
        while (t != null) {
            errorMessage = t.getLocalizedMessage();
            t = t.getCause();
        }

        return errorMessage;
    }

Registration.xhtml:

<p>
            <h:panelGrid columns="2">
                <h:commandButton id="register"
                    action="#{registrationController.register(registrationView.student)}" value="Register"
                    styleClass="register" />
                <h:messages styleClass="messages" errorClass="invalid"
                    infoClass="valid" warnClass="warning" globalOnly="true" />
            </h:panelGrid>
        </p>

这里的问题是,它只显示异常错误代码,如上所述。我想要的错误信息如下:

The user name has been registered, Please use another one. Thanks.

与SQL约束违规错误消息相比,这更加用户友好。怎么做到这一点?

2 个答案:

答案 0 :(得分:2)

我不确定你对“异常错误代码”的确切含义是什么?

在您的代码中,您明确地将Java Exception消息放在FacesMessage中。如果您希望向用户显示不同的内容,则应该在FacesMessage中编写不同的内容。

但是,我建议您在尝试保留之前简单地检查用户是否已经存在。您应该通过这种简单的预检查来涵盖大部分案例:

public void register (Student student) {
    if(service.exists(student)) {
        String message = "The user name has been registered, Please use another one. Thanks.";
        FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, 
                                         "Registration unsuccessful");
        facesContext.addMessage(null, m);
    } else {
        try {
            service.create(student);
        } catch (Exception e) {
            String errorMessage = getRootErrorMessage(e);
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, 
                                              "Registration unsuccessful");
            facesContext.addMessage(null, m);
        }
    }
}

除此之外,您还可以在SQLException中明确检查完整性约束违规,但是您无法通过这种方式区分不同类型的此类完整性约束违规。

public static boolean isConstraintViolation(SQLException e) {
    return e.getSQLState().startsWith("23");
}

您还可以检查错误消息是否包含字符串Duplicate entry,但这不是很可靠。

我更倾向于使用预检的第一个建议尝试。如果用户已存在,请向FacesContext添加适当的FacesMassages。它将涵盖大多数情况。在极不可能的情况下,当两个用户同时注册相同的用户名时,向用户显示“意外错误”。

答案 1 :(得分:-1)

我认为添加消息vs jsf生命周期有问题尝试创建一个PhaseListener来在faces上下文中添加消息,如下所示:

public class FacesMessagesListener implements PhaseListener {

    @Override
    public void afterPhase(final PhaseEvent event) {
           //add my messages to facesContext
    }

    @Override
    public void beforePhase(final PhaseEvent event) {
           //add my messages to facesContext
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }
}