14

我正在研究一种基于注释的方法来使用spring modules验证 Spring beans 。在本教程中,使用以下 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;  
}

如果不遵守特定验证规则,则使用的错误消息应遵循以下格式:

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.

消息键包含类名的事实带来了几个问题:

  1. 如果类被重命名,消息键也需要改变
  2. 如果我有另一个类(例如 Person),其电子邮件属性与 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;

但是我一次又一次地尝试了这个,它似乎不起作用。在使用此验证框架时,有没有人找到避免重复错误消息的方法?

4

3 回答 3

6

我快速浏览了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
}
于 2008-10-06T20:23:55.923 回答
2

Spring 验证确实有一个 ErrorCodeConverter 执行此操作:

org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter

使用此选项时,将检查资源包中的以下代码:

[errorCode.commandBeanName.fieldName, errorCode.fieldName, errorCode.fieldClassName, errorCode]

  • errorCode 是实际的验证错误代码,例如。not.blank,电子邮件。
  • commandBeanName 与引用表单支持 bean 的模型键名称相同。
  • fieldName 是字段的名称。
  • fieldClassName 是字段类名,例如。java.lang.String, java.lang.Integer

因此,例如,如果我有一个在模型中由键“formBean”引用的 bean,并且 java.lang.String 类型的字段 emailAddress 不包含电子邮件地址,这会导致 errorCode 电子邮件。验证框架将尝试解析以下消息代码:

[email.formBean.emailAddress、email.emailAddress、email.java.lang.String、email]

如果错误代码被错误代码“badEmail”替换,如下所示:

@Email(errorCode="badEmail")

框架将尝试解析的消息代码将是:

[badEmail.formBean.emailAddress, badEmail.emailAddress, badEmail.java.lang.String, badEmail]

我建议保持 errodCode 相同。因此,一条消息可用于所有与该 errorCode 相关联的字段。如果您需要更具体地使用某个字段的消息,您可以使用代码 errorCode.commandBeanName.field 将消息添加到资源包。

于 2012-06-22T14:41:30.393 回答
0

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"/>
于 2016-09-07T16:05:29.743 回答