jsr303 自定义消息
总览
本文将说明如何适应JSR 303验证API来从I18n属性文件加载消息,并通过保留国际化的所有好处和对多种语言的支持来实现这一点。
为此,我们将实现一个基于Spring API的自定义MessageInterpolator,用于管理I18N消息。
依存关系
在进行这项工作所需的maven依赖项下方,此处未列出Javax验证和Hibernate验证:
<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的配置
第一步是MessageSource bean的配置,它负责扫描和索引属性文件的内容。
<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来搜索并准备要显示的消息。
import java.util.Locale;import javax.validation.MessageInterpolator;import org.springframework.binding.message.MessageBuilder;
import org.springframework.context.MessageSource;public class SpringMessageInterpolator implements MessageInterpolator {@Autowiredprivate MessageSource messageSource, @Overridepublic 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();}@Overridepublic 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验证批注,validate将检查字段是否为空。 要使用定制的Spring消息插值器,我们需要在Spring Message源加载的属性文件之一上声明一条消息,让我们在ErrorMessages.properties上声明:
{com.myproject.validation.NotBlank} Mandatory field
最佳做法是将消息的键命名为我们的验证批注的完整类名,您可以随意选择任何键名,但必须在方括号{}之间才能使用。
我们的自定义注释将如下所示:
@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 {};
}
请确认message属性的默认值与您放入属性文件的默认值相同。
就是这样,现在您可以像平常一样使用批注,并且,如果不提供硬编码消息,则在属性文件中声明该消息后,它将从属性文件中加载。
翻译自: https://www.javacodegeeks.com/2014/07/jsr-303-loading-messages-from-an-i18n-property-file.html
jsr303 自定义消息