java 基于注解的 Spring bean 验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/149506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
annotation based Spring bean validation
提问by Dónal
I'm investigating an annotation-based approach to validating Spring beans using spring modules. In this tutorial, the following bean (getters and setters omitted) is used as an example:
我正在研究一种基于注释的方法来使用spring 模块验证 Spring bean 。在本教程中,使用以下 bean(省略了 getter 和 setter)作为示例:
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;
}
The error message that is used if a particular validation rule is disobeyed should follow this format:
违反特定验证规则时使用的错误消息应遵循以下格式:
bean-class.bean-propery[validation-rule]=Validation Error message
Examples for the class shown above include:
上面显示的类的示例包括:
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.
The fact that the message keys contain the class name presents a couple of problems:
消息键包含类名的事实提出了几个问题:
- If the class is renamed, the message keys also need to be changed
If I have another class (e.g. Person) with an email property that is validated identically to User.email, I need to duplicate the messages, e.g.
Person.email[not.blank]=Please enter your e-mail address.
Person.email[email]=Please enter a valid e-mail address.
Person.email[length]=Please enter no more than {2} characters.
- 如果类被重命名,则消息键也需要更改
如果我有另一个类(例如 Person)的电子邮件属性与 User.email 的验证相同,则我需要复制消息,例如
Person.email[not.blank]=请输入您的电子邮件地址。
Person.email[email]=请输入有效的电子邮件地址。
Person.email[length]=请输入不超过 {2} 个字符。
In fact, the documentation claims that is possible to configure a default message for a particular rule (e.g. @Email) like this:
事实上,文档声称可以为特定规则(例如@Email)配置默认消息,如下所示:
email=email address is invalid
This default message should be used if a bean-specific message for the rule cannot be found. However, my experience is that this simply does not work.
如果无法找到规则的 bean 特定消息,则应使用此默认消息。但是,我的经验是这根本行不通。
An alternative mechanism for avoiding duplicate messages is to pass the key of the error message to the rule annotation. For example, assume I have defined the following default error message for the @Email rule
避免重复消息的另一种机制是将错误消息的键传递给规则注释。例如,假设我已经为 @Email 规则定义了以下默认错误消息
badEmail=Email address is invalid
This message should be used if I annotate the relevant property like this:
如果我像这样注释相关属性,则应使用此消息:
@Email(errorCode="badEmail")
private String email;
However I tried this, out and again, it just doesn't seem to work. Has anyone found a way to avoid duplicating error messages when using this validation framework?
然而,我一次又一次地尝试了这个,它似乎不起作用。有没有人在使用此验证框架时找到避免重复错误消息的方法?
采纳答案by toolkit
I took a quick look at the BeanValidator API, and it looks like you might want to try the errorCodeConverterproperty.
我快速浏览了BeanValidator API,看起来您可能想尝试使用errorCodeConverter属性。
You would need to implement your own ErrorCodeConverter, or use one of the provided implementations?
您需要实现自己的ErrorCodeConverter,还是使用提供的实现之一?
....
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator"
p:configurationLoader-ref="configurationLoader"
p:errorCodeConverter-ref="errorCodeConverter" />
<bean id="errorCodeConverter" class="contact.MyErrorCodeConverter" />
....
Note: configurationLoader is another bean defined in the config XML used in the tutorial
注意:configurationLoader 是在教程中使用的配置 XML 中定义的另一个 bean
Example converter:
示例转换器:
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;
}
}
Now the properties should work:
现在属性应该可以工作:
MyEmailErrorCode=Bad email
class Foo {
@Email(errorCode="MyEmailErrorCode")
String email
}
回答by Rian
Spring validation does have an ErrorCodeConverter that does this:
Spring 验证确实有一个 ErrorCodeConverter 可以做到这一点:
org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter
org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter
When this is used, the resource bundle will be checked for the following codes:
使用时,将检查资源包中的以下代码:
[errorCode.commandBeanName.fieldName, errorCode.fieldName, errorCode.fieldClassName, errorCode]
[errorCode.commandBeanName.fieldName, errorCode.fieldName, errorCode.fieldClassName, errorCode]
- errorCode is the actual validation errorCode eg. not.blank, email.
- commandBeanName is the same as the model key name that references the form backing bean.
- fieldName is the name of the field.
- fieldClassName is the field class name eg. java.lang.String, java.lang.Integer
- errorCode 是实际的验证错误代码,例如。不是空白,电子邮件。
- commandBeanName 与引用表单支持 bean 的模型键名称相同。
- fieldName 是字段的名称。
- fieldClassName 是字段类名,例如。java.lang.String, java.lang.Integer
So for instance if I have a bean that is referenced in the model by the key "formBean" and the field emailAddress of type java.lang.String does not contain an email address, which causes the errorCode email. The validation framework will attempt to resolve the following message codes:
因此,例如,如果我有一个在模型中由键“formBean”引用的 bean,并且 java.lang.String 类型的字段 emailAddress 不包含电子邮件地址,这会导致 errorCode 电子邮件。验证框架将尝试解析以下消息代码:
[email.formBean.emailAddress, email.emailAddress, email.java.lang.String, email]
[email.formBean.emailAddress,email.emailAddress,email.java.lang.String,email]
If the errorCode is replaced by the errorCode "badEmail" like this:
如果 errorCode 被 errorCode "badEmail" 替换,如下所示:
@Email(errorCode="badEmail")
@Email(errorCode="badEmail")
The messages codes that the framework will try resolve will be:
框架将尝试解析的消息代码将是:
[badEmail.formBean.emailAddress, badEmail.emailAddress, badEmail.java.lang.String, badEmail]
[badEmail.formBean.emailAddress, badEmail.emailAddress, badEmail.java.lang.String, badEmail]
I would suggest keeping the errodCode the same. Thus one message can be used for all fields that have that errorCode associated with them. If you need to be more specific with the message for a certain field you can add a message to the resource bundles with the code errorCode.commandBeanName.field.
我建议保持 errodCode 不变。因此,一条消息可用于所有与该错误代码相关联的字段。如果您需要更具体地了解某个字段的消息,您可以使用代码 errorCode.commandBeanName.field 向资源包添加一条消息。
回答by VHS
Add the following beans in your applicationContext.xmlfile.
在您的applicationContext.xml文件中添加以下 bean 。
<bean id="configurationLoader"
class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" />
<!-- Use the error codes as is. Don't convert them to <Bean class name>.<bean field being validated>[errorCode]. -->
<bean id="errorCodeConverter"
class="org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter"/>
<!-- shortCircuitFieldValidation = true ==> If the first rule fails on a field, no need to check
other rules for that field -->
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator"
p:configurationLoader-ref="configurationLoader"
p:shortCircuitFieldValidation="true"
p:errorCodeConverter-ref="errorCodeConverter"/>

