основанная на аннотации проверка бина Spring - PullRequest
14 голосов
/ 29 сентября 2008

Я исследую основанный на аннотациях подход к проверке bean-компонентов Spring с использованием пружинных модулей . В этого урока в качестве примера используется следующий компонент (методы 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.

Тот факт, что ключи сообщений содержат имя класса, создает пару проблем:

  1. Если класс переименован, ключи сообщения также необходимо изменить
  2. Если у меня есть другой класс (например, Person) со свойством электронной почты, проверенный идентично User.email, мне нужно продублировать сообщения, например,

    Person.email [not.blank] = Пожалуйста, введите свой адрес электронной почты.
    Person.email [email] = Пожалуйста, введите действительный адрес электронной почты.
    Person.email [длина] = Пожалуйста, введите не более {2} символов.

На самом деле, в документации утверждается, что возможно настроить сообщение по умолчанию для определенного правила (например, @Email), например:

email=email address is invalid

Это сообщение по умолчанию следует использовать, если не может быть найдено специфичное для bean-сообщения сообщение для правила. Однако мой опыт показывает, что это просто не работает.

Альтернативный механизм, позволяющий избежать дублирования сообщений, - передать ключ сообщения об ошибке в аннотацию правила. Например, предположим, что я определил следующее сообщение об ошибке по умолчанию для правила @Email

badEmail=Email address is invalid

Это сообщение следует использовать, если я аннотирую соответствующее свойство следующим образом:

@Email(errorCode="badEmail")
private String email;

Однако я пробовал это время от времени, это, кажется, не работает. Кто-нибудь нашел способ избежать дублирования сообщений об ошибках при использовании этой структуры проверки?

Ответы [ 3 ]

6 голосов
/ 07 октября 2008

Я быстро взглянул на 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 - это еще один bean-компонент, определенный в XML-файле конфигурации, который используется в руководстве

Пример конвертера:

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
}
2 голосов
/ 22 июня 2012

Проверка Spring имеет ErrorCodeConverter, который делает это:

org.springmodules.validation.bean.converter.KeepAsIsErrorCodeConverter

Когда это используется, комплект ресурсов будет проверяться на наличие следующих кодов:

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

  • errorCode - это действительный код ошибки errorCode, например. not.blank, email.
  • commandBeanName совпадает с именем ключа модели, который ссылается на сформировать поддерживающий боб.
  • fieldName - это имя поля.
  • fieldClassName - имя класса поля, например. java.lang.String, java.lang.Integer

Так, например, если у меня есть bean-компонент, на который в модели ссылается ключ "formBean", а поле emailAddress типа java.lang.String не содержит адрес электронной почты, который вызывает ошибку errorCode. Среда проверки будет пытаться разрешить следующие коды сообщений:

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

Если код ошибки заменен кодом ошибки "badEmail", например:

@ E-mail (ERRORCODE = "badEmail")

Коды сообщений, которые фреймворк попытается разрешить, будут:

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

Я бы предложил оставить код errod таким же. Таким образом, одно сообщение может использоваться для всех полей, с которыми связан этот код ошибки. Если вам нужно быть более конкретным с сообщением для определенного поля, вы можете добавить сообщение к пакетам ресурсов с кодом errorCode.commandBeanName.field.

0 голосов
/ 07 сентября 2016

Добавьте следующие bean-компоненты в ваш файл applicationContext.xml.

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