JSF在转换之前保存输入值

时间:2013-07-25 09:26:59

标签: jsf converter state

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

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

1 个答案:

答案 0 :(得分:1)

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

除自定义转换器外,您还需要一个自定义验证器。在验证程序中,如果已转换输入与数据库上的数据之间的检查成功,则自定义转换器的getAsString将仅返回已转换的输入。但是,如果转换成功但验证失败(意味着对db记录的检查不成功),那么您只需抛出ValidatorException。将不会调用getAsString并显示原始输入。

我可以通过两种方式思考如何实现这一目标。对于第一种方法,您可以在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,某些方面将变得更加清晰。这是一个很好的起点。

Debug JSF lifecycle