Spring 如何自定义Hibernate@Size错误消息以指示输入字段的长度

Spring 如何自定义Hibernate@Size错误消息以指示输入字段的长度,spring,hibernate,validation,Spring,Hibernate,Validation,我想自定义文本字段的错误消息,以包括实际输入的字符数。我已经能够做到这一点,但对我的解决方案并不满意,所以我想知道其他人做了什么来实现这一点 春季4.1.2 休眠4.3.10 Hibernate验证程序5.1.3 字段注释(出于测试目的,限制为10个-实际大小为150) 消息.属性 Size.person.name=Maximum is {1} characters JSP代码 <spring:bind path="person.name"> <c

我想自定义文本字段的错误消息,以包括实际输入的字符数。我已经能够做到这一点,但对我的解决方案并不满意,所以我想知道其他人做了什么来实现这一点

  • 春季4.1.2
  • 休眠4.3.10
  • Hibernate验证程序5.1.3
字段注释(出于测试目的,限制为10个-实际大小为150)

消息.属性

Size.person.name=Maximum is {1} characters
JSP代码

    <spring:bind path="person.name">
        <c:set var="nameError">${status.errorMessage}</c:set>
        <c:set var="nameDisplayValue">${status.displayValue}</c:set>
        <c:set var="nameCode">${status.errorCode}</c:set>
    </spring:bind>
    <c:if test="${fn:contains(nameCode,'Size')}">
        <c:set var="nameLen">${fn:length(nameDisplayValue)}</c:set>
        <c:if test="${nameLen gt 0}">
            <c:set var="nameError">${nameError += " (you entered " += nameLen += ")"}</c:set>  
        </c:if>
    </c:if>

    <div class="form-group col-sm-9 <c:if test="${not empty nameError}">has-error</c:if>">
        <label class="control-label" id="nameLabel" for="inputName">Name:<c:if test="${not empty nameError}">&nbsp;&nbsp;${nameError}</c:if></label>
        <form:input type="text" size="10" class="form-control" id="inputName" placeholder="Name" path="name" autocomplete="off"/>                                                           
    </div>

${status.errorMessage}
${status.displayValue}
${status.errorCode}
${fn:length(nameDisplayValue)}
${nameError+=”(您输入了“+=nameLen+=”)}
名称:${nameError}
输出

对于一个字段来说这是可以的,但是我正在处理的表单有10多个字段进行了大小验证。此外,form:input的size=“10”设置似乎并不实际执行任何操作,也就是说,您仍然可以输入10个以上的字符


我知道有一种选择是编写一个自定义验证器,但对于我想做的事情来说,这似乎有些过头了。另一种方法是在发布表单之前捕获错误,但我正在尝试将所有验证保留在服务器端。如果您有任何建议,我们将不胜感激。

关于在Hibernate文档中插入验证消息,有一个很好的文档:

如果在类路径的根目录中创建一个文件
ValidationMessages.properties
,则可以在那里更改所有验证消息:

javax.validation.constraints.Size.message=Please enter at least {min} and at most {max} characters.
{…}
中的参数只是注释的属性名。这几乎适用于所有约束。如果要引用已验证的值,可以使用
{validatedValue}
。您也可以使用
Formatter
格式化值:

... ${formatter.format('...', validatedValue)} ...
不幸的是,没有长度格式字符串

因此,如果您真的想为所有
@Size
用户提供这样的消息,那么您必须实现自己的
javax.validation.MessageInterpolator
(请参阅上面链接中的自定义消息插值)

附加备注:更改默认验证消息时会产生副作用:
@Size
也可用于集合。在这种情况下,至少我的信息是不合适的。我通常会为此创建第二条验证消息:

javax.validation.constraints.Size.Collection.message=Please select at least {min} and at most {max} elements.
并在约束中使用该选项:

public final class ValidationMessages {
  public static final String COLLECTION_SIZE = 
      "javax.validation.constraints.Size.Collection.message";
}

public class MyClass {
    @Size(min = 1, max = 10, message = ValidationMessages.COLLECTION_SIZE)
    private Collection<String> elements;
}
公共最终类验证消息{
公共静态最终字符串集合\u大小=
“javax.validation.constraints.Size.Collection.message”;
}
公共类MyClass{
@大小(最小值=1,最大值=10,消息=ValidationMessages.COLLECTION\u大小)
私人收藏元素;
}

通过在我的代码样式工具中使用匹配规则,我确保不会忘记为集合上的
@Size
注释定义消息。

关于集合的好观点。但我要寻找的是一个额外的参数,它将显示输入字符的实际数量
Size.recipe.name=最大值为{max}个字符(您输入了{length})
对不起,在我的代码中挖掘后忘记了这一点。我现在已经添加了。谢谢你的回复。我看过很多帖子,如果我想在服务器端执行此操作,恐怕您关于实现自定义插值器的想法可能是正确的。@LWK69如果您有答案,我很想知道您是如何解决此问题的。
public final class ValidationMessages {
  public static final String COLLECTION_SIZE = 
      "javax.validation.constraints.Size.Collection.message";
}

public class MyClass {
    @Size(min = 1, max = 10, message = ValidationMessages.COLLECTION_SIZE)
    private Collection<String> elements;
}