Статьи

JSR 303 загрузка сообщений из файла свойств I18N

обзор

В этой статье будет показано, как адаптировать API проверки JSR 303 для загрузки сообщений из файла свойств I18n, сохранив при этом все преимущества интернационализации и поддержку нескольких языков.

Чтобы добиться этого, мы собираемся реализовать собственный MessageInterpolator, который будет основан на Spring API для управления сообщениями I18N.

зависимости

Ниже обязательных зависимостей maven, чтобы это работало, проверка Javax и проверка Hibernate не перечислены здесь:

01
02
03
04
05
06
07
08
09
10
11
12
<dependencies>
     <dependency>
         <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.0.0.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.springframework.webflow</groupId>
          <artifactId>spring-binding</artifactId>
          <version>2.3.2.RELEASE</version>
    </dependency>
</dependencies>

Конфигурация MessageSource

Первым шагом является настройка bean-компонента MessageSource, который отвечает за сканирование и индексацию содержимого файлов свойств.

1
2
3
4
5
6
7
8
9
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="basenames">
            <list>
                <value>com.myproject.i18n.MyMessages</value>
                <value>com.myproject.i18n.ErrorMessages</value>
            </list>
        </property>
    </bean>

MyMessages и ErrorMessages — это файлы свойств, которые мы хотели сканировать, имена файлов поддерживают соглашения для нескольких языков.

Например, если наше приложение должно поддерживать английский и французский языки, мы должны иметь: MyMessages_en.properties и MyMessages_fr.properties.

Пользовательский MessageInterpolator

В этом пользовательском MessageInterpolator мы переопределяем способ разрешения сообщений, отображаемых в JSR 303, и предоставляем пользовательскую реализацию, которая использует Spring MessagesSource и MessageBuild для поиска и подготовки к отображению сообщения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.util.Locale;
 
import javax.validation.MessageInterpolator;
 
import org.springframework.binding.message.MessageBuilder;
import org.springframework.context.MessageSource;
 
public class SpringMessageInterpolator implements MessageInterpolator {
    @Autowired
    private MessageSource messageSource,
 
    @Override
    public String interpolate(String messageTemplate, Context context) {
        String[] params = (String[]) context.getConstraintDescriptor().getAttributes().get("params");
 
        MessageBuilder builder = new MessageBuilder().code(messageTemplate);
        if (params != null) {
            for (String param : params) {
                builder = builder.arg(param);
            }
        }
 
        return builder.build().resolveMessage(messageSource, Locale.FRANCE).getText();
    }
 
    @Override
    public String interpolate(String messageTemplate, Context context, Locale locale) {
        String[] params = (String[]) context.getConstraintDescriptor().getAttributes().get("params");
 
        MessageBuilder builder = new MessageBuilder().code(messageTemplate);
        if (params != null) {
            builder = builder.args(params);
        }
 
        return builder.build().resolveMessage(messageSource, local).getText();
    }
}

Использование на заказ JSR 303

Допустим, мы создали новую аннотацию валидации JSR 303, которая проверит, не является ли поле пустым. Чтобы использовать пользовательский интерполятор сообщений Spring, нам нужно объявить сообщение в одном из файлов свойств, загруженных источником сообщений Spring, давайте объявим это в ErrorMessages.properties:

1
{com.myproject.validation.NotBlank}    Mandatory field

Рекомендуется называть ключ сообщения как полное имя classe нашей аннотации проверки, вы можете выбрать любое имя ключа, которое хотите, но оно должно быть в скобках {} для работы.

Наша пользовательская аннотация будет выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = NotBlankValidator.class)
public @interface NotBlank {
    String message() default "{com.myproject.validation.NotBlank";
 
    Class<?>[] groups() default {};
 
    String[] params() default {};
 
    Class<? extends Payload>[] payload() default {};
}

Убедитесь, что значение по умолчанию атрибута сообщения совпадает с тем, которое вы указали в файле свойств.

Вот так, теперь вы можете использовать аннотацию, как обычно, и если вы не предоставите жестко закодированное сообщение, оно будет загружено из файла свойств, если оно там объявлено.

Ссылка: JSR 303 загружает сообщения из файла свойств I18N от нашего партнера по JCG Идрисса Мрабти в блоге Fancy UI .