基于注解的Spring bean验证
时间:2020-03-06 14:53:01 来源:igfitidea点击:
我正在研究一种基于注释的方法,用于使用spring模块验证Spring bean。在本教程中,以以下bean(省略了getter和setters)为例:
public final class User {
@NotBlank
@Length(max = 80)
private String name;
@NotBlank
@Email
@Length(max = 80)
private String email;
@NotBlank
@Length(max = 4000)
private String text;
}
如果不遵守特定的验证规则,则使用的错误消息应遵循以下格式:
bean-class.bean-propery[validation-rule]=Validation Error message
上面显示的类的示例包括:
User.email[not.blank]=Please enter your e-mail address.
User.email[email]=Please enter a valid e-mail address.
User.email[length]=Please enter no more than {2} characters.
消息键包含类名的事实带来了两个问题:
- 如果重命名了类,则还需要更改消息键
- 如果我有另一个类(例如,人),其电子邮件属性已与User.email进行了相同的验证,则需要复制消息,例如Person.email [not.blank] =请输入电子邮件地址。 Person.email [email] =请输入有效的电子邮件地址。 Person.email [length] =请输入不超过{2}个字符。
实际上,文档声称可以为特定规则(例如@Email)配置默认消息,如下所示:
email=email address is invalid
如果找不到针对该规则的特定于Bean的消息,则应使用此默认消息。但是,我的经验是,这根本行不通。
避免重复消息的另一种机制是将错误消息的密钥传递给规则注释。例如,假设我为@Email规则定义了以下默认错误消息
badEmail=Email address is invalid
如果我这样注释相关属性,则应使用此消息:
@Email(errorCode="badEmail") private String email;
但是我一遍又一遍地尝试了一下,但它似乎没有用。有没有人找到使用此验证框架时避免重复出现错误消息的方法?
解决方案
我快速浏览了BeanValidator API,看来我们可能想尝试使用errorCodeConverter属性。
我们是否需要实现自己的ErrorCodeConverter或者使用提供的实现之一?
....
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator"
p:configurationLoader-ref="configurationLoader"
p:errorCodeConverter-ref="errorCodeConverter" />
<bean id="errorCodeConverter" class="contact.MyErrorCodeConverter" />
....
注意:configurationLoader是在本教程中使用的config XML中定义的另一个bean
转换器示例:
package contact;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springmodules.validation.bean.converter.ErrorCodeConverter;
public class MyErrorCodeConverter implements ErrorCodeConverter {
private Log log = LogFactory.getLog(MyErrorCodeConverter.class);
@Override
public String convertPropertyErrorCode(String errorCode, Class clazz, String property) {
log.error(String.format("Property %s %s %s", errorCode, clazz.getClass().getName(), property));
return errorCode; // <------ use the errorCode only
}
@Override
public String convertGlobalErrorCode(String errorCode, Class clazz) {
log.error(String.format("Global %s %s", errorCode, clazz.getClass().getName()));
return errorCode;
}
}
现在,这些属性应该可以正常工作:
MyEmailErrorCode=Bad email
class Foo {
@Email(errorCode="MyEmailErrorCode")
String email
}

