0

我有一个输入字段,用户可以在其中输入他们的社会安全号码(用户 ID)。这个数字必须是某种格式,所以我使用自定义转换器来正确格式化它。稍后将根据数据库检查该号码。当检查失败时,出于 UX 原因,我希望以用户输入的方式显示数字。但是转换是在检查之前,并且支持 bean 中的 userid 设置为转换后的值,原始数字丢失了。保存原始值的最佳方法是什么?

<h:inputText id="userId" value="#{bean.userId}">
    <f:converter converterId="IdConverter" />
</h:inputText>
4

1 回答 1

1

如果我正确理解您的问题,那么您不需要保存原始值。利用 JSF 生命周期。

除了自定义转换器之外,您还需要自定义验证器。在您的验证器中,如果转换后的输入与数据库上的数据之间的检查成功,那么getAsString您的自定义转换器将简单地返回转换后的输入。但是,如果转换成功但验证失败(意味着对 db 记录的检查不成功),那么您将简单地抛出ValidatorExceptiongetAsString不会被调用,原始输入将被显示。

关于如何实现这一目标,我可以想到两种方法。对于第一种方法,您可以在 bean 中定义一个验证器方法,并在该方法中移动您的验证逻辑。例子 :

public class Bean {    
    //Remainder omitted

    public void validate(FacesContext fc, UIComponent uic, Object o) {
        //Get the converted input. Assuming of type String
         String convertedInput = (String) o; 

        //Move the db check in this method. If it fails simply throw 
        //a ValidatorException like below. If it succeeds, don't return anything

        //throw new ValidatorException(new FacesMessage("Validation Failed")); 
    }
} 

注意返回类型和参数。

然后你会像这样添加validator属性<h:inputText>

<h:inputText id="userId" value="#{bean.userId}" validator="#{bean.validate}">

这种方法的一个优点是该方法将能够访问Bean该类的其他实例变量,但缺点是它的可移植性较差。

另一种方法是让一个单独的类实现Validator接口。例子:

@FacesValidator("customValidator")
public class MyValidator implements javax.faces.validator.Validator {

    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) {
        //Same logic as bean validator method
    }
}

然后添加你的<h:inputText>

<f:validator validatorId="customValidator" />

您的问题似乎表明对 JSF 生命周期缺乏了解。我强烈建议您花时间尽可能多地理解这个概念。您可能无法一口气理解它,但是随着您对 JSF 的参与越来越多,某些方面会变得更加清晰。这是一个很好的起点。

调试 JSF 生命周期

于 2013-07-26T17:52:34.227 回答