【问题标题】:JSF 2 : How handle exceptions in controller?JSF 2:如何处理控制器中的异常?
【发布时间】:2012-09-11 23:49:55
【问题描述】:

我想做一个可以正常工作的注册表:

<h:form id="register_form">
            <h:panelGrid columns="3">
                <h:outputLabel for="email" value="E-mail:" />
                <h:inputText id="email" value="#{userc.userb.user.email}">
                    <f:ajax event="blur" render="m_email" />
                </h:inputText>
                <h:message id="m_email" for="email" ajaxRendered="false" />

                <h:outputLabel for="password" value="Passoword" />
                <h:inputSecret id="password" value="#{userc.userb.user.password}">
                    <f:validator validatorId="confirmPasswordValidator" />
                    <f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
                </h:inputSecret>
                <h:message id="m_password" for="password" />

                <h:commandButton value="Registerr" action="#{userc.register}">
                    <f:ajax execute="@form" render="@form" />
                </h:commandButton>
                
                <h:messages globalOnly="true" layout="table" />
                
            </h:panelGrid>
        </h:form>

这是我的控制器:

public void register(){
    FacesMessage message;
    try {
        userb.encryptPassword();
        userEAO.create(userb.getUser());
        
        message = new FacesMessage("Register successfully!");
        FacesContext.getCurrentInstance().addMessage(null, message);
    } catch (Exception e) {
        // 1062 : duplicate entry
        if (e.getMessage().contains("Duplicate")){
            message = new FacesMessage("User already registered, please try another email");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }else{
            message = new FacesMessage("An error occured, try again please");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }
    
}

因此,例如,如果某个用户尝试注册自己两次,我会返回此消息,说这是重复的,但我想知道这是否是最好的方法。

如何处理这些异常?

【问题讨论】:

  • 你为什么不检查一下 userb.getUser() 并根据它确定要做什么。如果其重复或有错误。两种方法都可以解决问题。

标签: java exception jsf jsf-2


【解决方案1】:

这些验证应该由您的业务逻辑层对象处理,在这种情况下,它看起来像是userEAO 对象。您可以决定是否应该以异常的形式处理此错误消息(恕我直言,不会使用)。

就我而言,我更喜欢使用Message 类,它基本上包含一个整数代码和一个保存操作结果的消息。对于我的情况,我通常返回 0 或更多表示操作成功,并使用负代码来声明错误。这是一个非常基本的例子:

public class Message {
    private int code;
    private String message;
    //constructor...
    //getters and setters...
}

public class UserBL {

    public Message create(User user) {
        //do some fancy validations
        if (!verifyDuplicatedUser(user)) {
            return new Message(-1000, "Duplicated user");
        }
        //and the operations...
        saveUser(user);
        return new Message(0, "Register successfully!");
    }

}

现在您的控制器将转发到它真正必须做的事情(这意味着,没有繁重的业务逻辑验证):

public void register() {
    FacesMessage fmessage;
    userb.encryptPassword();
    Message message = userEAO.create(userb.getUser());
    fmessage = new FacesMessage(message.getMessage());
    FacesContext.getCurrentInstance().addMessage(null, fmessage);
}

当您应该验证一组数据时,这种方法甚至可以帮助您,例如验证 Excel 工作表的结果并且您必须显示错误列表(因为多次显示单个错误非常烦人!)。

您可以改进创建消息的方式,例如从包含系统消息的表中检索它们,或使用属性文件来处理国际化(当然,这取决于您的功能要求)。

【讨论】:

  • 好点路易吉。但是我应该如何处理异常?例如,当它是重复条目时?
  • 不知怎么知道是哪个异常才知道怎么处理,明白吗?
  • 重复条目可能是也可能不是例外,这取决于您的观点。在我看来,这是一个应用程序错误,您可以使用 if/else 语句来处理。请记住,处理一般的Exception 是一个非常糟糕的主意,会占用系统中的资源,使用e.getMessage().contains(&lt;whatever&gt;) 很难维护和阅读。我提出的解决方案更容易维护,对新人来说更易读,更灵活,并将业务逻辑与托管 Bean 和业务层分开,最后一个应该做艰苦而肮脏的工作。
  • 请记住:您应该将应用程序错误(如重复的用户验证)和 Java 异常(IndexOutOfBounds 或 DivisionByZero)分开,您应该使用不同的方法处理两者。这真的取决于你的设计。
猜你喜欢
  • 1970-01-01
  • 2016-01-11
  • 2015-06-17
  • 2013-06-07
  • 2013-03-04
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多