В JSF проверка происходит после преобразования.Если вы введете что-то, не являющееся числом, в текстовое поле, которое сопоставлено с BigDecimal в компоненте поддержки, JSF попытается преобразовать это в BigDecimal, и это, конечно, не удастся.Таким образом, Hibernate Validator на самом деле не получит шанса. Вам нужно будет локализовать конверсионные сообщения JSF, чтобы достичь желаемого.
Я не знаком с аннотацией @Digits.Но документы Hibernate Validator , кажется, указывают, что он проверяет, использует ли число ожидаемое количество целых и дробных цифр.Поэтому вместо ввода текста в текстовое поле попробуйте ввести значение, которое не соответствует формату, принятому валидатором (в вашем случае дробная = 2, целое = 13).Поэтому попробуйте ввести значение 123.123120 и посмотреть, получите ли вы ожидаемое сообщение.
Вот хак, чтобы пройти весь путь до сущностей и получить аннотации в конвертере.Сначала вам нужно создать собственный конвертер для числа (в данном случае, BigDecimal):
@FacesConverter("MyBigDecimalConverter")
public class MyBigDecimalConverter extends NumberConverter {
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
try {
HtmlInputText it = (HtmlInputText) arg1;
ValueExpression ve = it.getValueExpression("value");
String expression = ve.getExpressionString();
String field = expression.replaceAll("#\\{.*\\.", "");
field = field.replace("}", "");
String parent = expression.replace("." + field, "");
ExpressionFactory expressionFactory = arg0.getApplication().getExpressionFactory();
ValueExpression exp = expressionFactory.createValueExpression(arg0.getELContext(), parent, Object.class);
Object obj = exp.getValue(arg0.getELContext());
Digits d = null;
Field f = obj.getClass().getDeclaredField(field);
d = f.getAnnotation(Digits.class);
return super.getAsObject(arg0, arg1, arg2);
} catch (ConverterException e) {
FacesMessage msg = new FacesMessage(d.message());
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ConverterException(msg);
} catch (Exception e) {
return super.getAsObject(arg0, arg1, arg2);
}
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
return super.getAsString(arg0, arg1, arg2);
}
}
И вам нужно использовать этот конвертер на своей странице:
<h:outputText value="#{someBean.someEntity.nome}" />
<h:form>
<p:inputText value="#{someBean.someEntity.someBigDecimal}" id="test">
<f:converter converterId="MyBigDecimalConverter" />
</p:inputText>
<h:message for="test"></h:message>
<p:commandButton value="teste" process="@form" update="@form"></p:commandButton>
</h:form>
Яздесь используются компоненты primeFaces, но они вам на самом деле не нужны.
Что именно делает конвертер?Он выбирает объект в вашем бине, который содержит значение, на которое ссылается inputText, и имя поля.Затем он находит аннотацию @Digits для этого поля и читает его сообщение.Он просит NumericConverter преобразовать строку в число.Если это не удается, он использует сообщение в аннотации @Digits для сообщения об ошибке.