gpt4 book ai didi

java - 为什么我的 bean 验证消息没有被接收到?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:54:21 26 4
gpt4 key购买 nike

我正在为以后的 i18n 定义一些 bean 验证消息。此消息应验证输入的类型为 number/BigDecimal:

class Payment {
@Digits(message = "test error msg", fraction = 2, integer = 13)
private BigDecimal amount;
}

<p:inputText value="#{payment.amount}" />

不幸的是,如果我尝试输入文本,我没有得到我定义的信息,但是:

'asd' must be a signed decimal number

谁能解释一下为什么?或者更确切地说,如何强制我的输入字段始终使用 @Digits 进行验证?

最佳答案

在 JSF 中,验证发生在之后 转换。如果您在映射到支持 bean 中的 BigDecimal 的文本字段中输入的不是数字,JSF 将尝试将其转换为 BigDecimal,当然会失败。所以 Hibernate Validator 不会真正有机会发挥作用。您需要本地化 JSF 转换消息以实现您想要的。

我不熟悉@Digits 注释。但是 Hibernate Validator docs似乎表明它验证该数字是否正在使用预期数量的整数和小数位数。因此,不要在文本字段中输入文本,而是尝试输入一个与 validator 接受的格式不同的值(在您的例子中,分数 = 2,整数 = 13)。因此,请尝试输入值 123.123120 并查看是否收到预期的消息。

这是进入实体并在转换器处获取注释的 hack。首先,您需要为数字创建一个自定义转换器(在本例中为 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 组件,但您并不真正需要它们。

转换器到底在做什么?它正在获取 bean 中的对象,该对象包含 inputText 引用的值和字段名称。然后,它找到该字段的 @Digits 注释并读取它的消息。它要求 NumericConverter 将字符串转换为数字。如果失败,它将使用@Digits 注释中的消息作为错误消息。

关于java - 为什么我的 bean 验证消息没有被接收到?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9484163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com