JSF转换器导致验证器被忽略 [英] JSF converter causes validator(s) to be ignored

查看:113
本文介绍了JSF转换器导致验证器被忽略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是字段:

<h:inputText id="mobilePhoneNo"
             value="#{newPatientBean.phoneNo}"
             required="true"
             requiredMessage="Required"
             validator="#{mobilePhoneNumberValidator}"
             validatorMessage="Not valid (validator)"
             converter="#{mobilePhoneNumberConverter}"
             converterMessage="Not valid (converter)"
             styleClass="newPatientFormField"/>

验证器:

@Named
@ApplicationScoped
public class MobilePhoneNumberValidator implements Validator, Serializable
{
    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException
    {
        // This will appear in the log if/when this method is called.
        System.out.println("mobilePhoneNumberValidator.validate()");

        UIInput in = (UIInput) uic;
        String value = in.getSubmittedValue() != null ? in.getSubmittedValue().toString().replace("-", "").replace(" ", "") : "";

        if (!value.matches("04\\d{8}"))
        {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please enter a valid mobile phone number.", null));
        }
    }
}

当我按下命令按钮时在表单中,我得到以下行为:

When I press the command button within the form, I get the following behaviour:


  • 当该字段为空时,消息为无效(转换器)。

  • 当该字段具有有效条目时,消息为无效(验证者)。

  • 当该字段包含无效条目时,该消息是无效(转换器)。

在所有三种情况下, MobilePhoneNumberConverter.getAsObject()被调用。 MobilePhoneNumberValidator.validate() 从不被调用。当该字段为空时,它会忽略 required =true属性并直接进行转换。

In all three cases, MobilePhoneNumberConverter.getAsObject() is called. MobilePhoneNumberValidator.validate() is never called. And when the field is blank, it ignores the required="true" attribute and proceeds straight to conversion.

我原以为正确的行为是:

I would have thought the proper behaviour would be:


  • 当该字段为空时,该消息应为必填。

  • 当该字段具有有效条目时,根本不应该有任何消息。

  • 当该字段包含无效条目时,该消息应为无效(验证器)。

  • 如果通过转换传递的验证没有,则消息应为无效(转换器)。

  • When the field is blank, the message should be "Required".
  • When the field has a valid entry, there should be no message at all.
  • When the field has an invalid entry, the message should be "Not valid (validator)".
  • If, by some chance, validation passed by conversion didn't, the message should be "Not valid (converter)".

注意:支持bean是请求范围的,因此这里没有花哨的AJAX业务。

Note: The backing bean is request scoped, so there's no fancy AJAX business going on here.

更新:

可能与 javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL 设置为 true

推荐答案

转换在验证前发生。当值 null 或为空时,也将调用转换器。如果要将 null 值委托给验证器,那么您需要设计它只返回的转换器 null 当提供的值 null 或为空时。

Conversion happens before validation. Converters will also be called when the value is null or empty. If you want to delegate the null value to the validators, then you need to design your converters that it just returns null when the supplied value is null or empty.

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.trim().isEmpty()) {
        return null;
    }

    // ...
}



< hr>

无关到具体问题,你的验证器有一个缺陷。您不应该从组件中提取提交的值。 与转换器返回的值相同。正确提交和转换的值已作为第3个方法参数提供。


Unrelated to the concrete problem, your validator has a flaw. You should not extract the submitted value from the component. It's not the same value as returned by the converter. The right submitted and converted value is available as the 3rd method argument already.

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (value == null) {
        return; // This should normally not be hit when required="true" is set.
    }

    String phoneNumber = (String) value; // You need to cast it to the same type as returned by Converter, if any.

    if (!phoneNumber.matches("04\\d{8}")) {
        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please enter a valid mobile phone number.", null));
    }
}

这篇关于JSF转换器导致验证器被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆