2008-09-29 146 views
14

我正在研究基於註釋的方法來驗證Spring beans,使用spring modules。在this tutorial,以下豆(省略getter和setter)被用作例如:基於註釋的Spring bean驗證

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; 

不過,我想這一點,一次又一次,它似乎並沒有工作。有沒有人找到一種方法來避免使用此驗證框架時重複錯誤消息?

回答

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是在教程中使用的配置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 
} 
+0

在上面顯示的Spring配置中,什麼是configurationLoader bean? – 2008-10-07 15:33:08

2

Spring驗證確實有一個ErrorCod eConverter,這是否:

org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter

當這樣使用時,資源束將被檢查爲以下代碼:

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

  • errorCode是實際的驗證errorCode例如。 not.blank,電子郵件。
  • commandBeanName與引用 表單支持bean的模型鍵名相同。
  • fieldName是該字段的名稱。
  • fieldClassName是字段類的名稱,例如。 java.lang.String中,爲java.lang.Integer

因此,舉例來說,如果我有一個是在模型的關鍵「的formBean」和java.lang.String類型的字段EMAILADDRESS引用的Bean不包含一個電子郵件地址,它會導致errorCode電子郵件。驗證框架將嘗試解決以下消息代碼:

[email.formBean.emailAddress,email.emailAddress,email.java.lang.String,電子郵件]

如果錯誤碼爲用的errorCode改爲「 badEmail」是這樣的:

@Email(錯誤碼= 「badEmail」)

中的消息代碼,該框架將試圖解決將是:

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

我建議保持errodCode相同。因此,一條消息可以用於具有與它們相關的errorCode的所有字段。如果您需要針對特定​​字段的消息更加具體,則可以使用代碼errorCode.commandBeanName.field將消息添加到資源包中。

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"/>