Springboot international information (i18n) resolved

International understanding information

International information is also known as the locale. Java objects are represented by localized java.util.Locale class, it creates a localized objects determined by the "language type" and "country / region." To give an example, such as sending a specific request when a key is provided in the header of: "Accept-Language": "zh", by a value corresponding to the Accept-Language, the server can determine which area used language, find the corresponding resource file, formatting, and then returned to the client.

MessageSource

Spring defines MessageSource interface for accessing international information.

  • getMessage(String code, Object[] args, String defaultMessage, Locale locale)
  • getMessage(String code, Object[] args, Locale locale)
  • getMessage(MessageSourceResolvable resolvable, Locale locale)

 

 MessageSourceAutoConfiguration

 springboot provides information on international automatic configuration, configuration, registered in the ResourceBundleMessageSource implementation class.

 1 @Configuration
 2 @ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT)
 3 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
 4 @Conditional(ResourceBundleCondition.class)
 5 @EnableConfigurationProperties
 6 public class MessageSourceAutoConfiguration {
 7 
 8     private static final Resource[] NO_RESOURCES = {};
 9 
10     @Bean
11     @ConfigurationProperties(prefix = "spring.messages")
12     public MessageSourceProperties messageSourceProperties() {
13         return new MessageSourceProperties();
14     }
15 
16     @Bean
17     public MessageSource messageSource(MessageSourceProperties properties) {
18         ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
19         if (StringUtils.hasText(properties.getBasename())) {
20             messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
21                     StringUtils.trimAllWhitespace(properties.getBasename())));
22         }
23         if (properties.getEncoding() != null) {
24             messageSource.setDefaultEncoding(properties.getEncoding().name());
25         }
26         messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
27         Duration cacheDuration = properties.getCacheDuration();
28         if (cacheDuration != null) {
29             messageSource.setCacheMillis(cacheDuration.toMillis());
30         }
31         messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
32         messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
33         return messageSource;
34     }
35 
36     protected static class ResourceBundleCondition extends SpringBootCondition {
37 
38         private static ConcurrentReferenceHashMap<String, ConditionOutcome> cache = new ConcurrentReferenceHashMap<>();
39 
40         @Override
41         public ConditionOutcome getMatchOutcome(ConditionContext context,
42                 AnnotatedTypeMetadata metadata) {
43             String basename = context.getEnvironment()
44                     .getProperty("spring.messages.basename", "messages");
45             ConditionOutcome outcome = cache.get(basename);
46             if (outcome == null) {
47                 outcome = getMatchOutcomeForBasename(context, basename);
48                 cache.put(basename, outcome);
49             }
50             return outcome;
51         }
52 
53         private ConditionOutcome getMatchOutcomeForBasename(ConditionContext context,
54                 String basename) {
55             ConditionMessage.Builder message = ConditionMessage
56                     .forCondition("ResourceBundle");
57             for (String name : StringUtils.commaDelimitedListToStringArray(
58                     StringUtils.trimAllWhitespace(basename))) {
59                 for (Resource resource : getResources(context.getClassLoader(), name)) {
60                     if (resource.exists()) {
61                         return ConditionOutcome
62                                 .match(message.found("bundle").items(resource));
63                     }
64                 }
65             }
66             return ConditionOutcome.noMatch(
67                     message.didNotFind("bundle with basename " + basename).atAll());
68         }
69 
70         private Resource[] getResources(ClassLoader classLoader, String name) {
71             String target = name.replace('.', '/');
72             try {
73                 return new PathMatchingResourcePatternResolver(classLoader)
74                         .getResources("classpath*:" + target + ".properties");
75             }
76             catch (Exception ex) {
77                 return NO_RESOURCES;
78             }
79         }
80 
81     }
82 
83 }
View Code

First MessageSource configuration takes effect relies on a ResourceBundleCondition condition, read spring.messages.basename corresponding value from the environment variable, the default value is the messages, the value is MessageSource corresponding resource file name, file extension resource is .properties, then PathMatchingResourcePatternResolver from the "classpath *:" reads the corresponding directory resource file, if they can properly read to the resource file, load the configuration class.

 

 springmvc automatic assembly configuration class, a register RequestContextFilter filter.

 Each request, LocaleContextHolder will save the locale of the current request.

 By MessageSourceAccessor get specific information according to the time code, the default configuration if the object is empty localization, through LocaleContextHolder acquired.

 messageSource The figure is the application context object (created for this article is GenericWebApplicationContext example), the messageSource object calls ResourceBundleMessageSource instance get specific information.

ValidationAutoConfiguration

Hibernate-validator calibration parameters are loaded by the automatic assembly come.

 1 @Configuration
 2 @ConditionalOnClass(ExecutableValidator.class)
 3 @ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider")
 4 @Import(PrimaryDefaultValidatorPostProcessor.class)
 5 public class ValidationAutoConfiguration {
 6 
 7     @Bean
 8     @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 9     @ConditionalOnMissingBean(Validator.class)
10     public static LocalValidatorFactoryBean defaultValidator() {
11         LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
12         MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();
13         factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
14         return factoryBean;
15     }
16 
17     @Bean
18     @ConditionalOnMissingBean
19     public static MethodValidationPostProcessor methodValidationPostProcessor(
20             Environment environment, @Lazy Validator validator) {
21         MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
22         boolean proxyTargetClass = environment
23                 .getProperty("spring.aop.proxy-target-class", Boolean.class, true);
24         processor.setProxyTargetClass(proxyTargetClass);
25         processor.setValidator(validator);
26         return processor;
27     }
28 
29 }
View Code

MethodValidationPostProcessor The post processing method in a single parameter check annotations (JSR and Hibernate validator can check (i.e. Bean Domain Object's attributes) verify, the individual parameters can not be verified.).

LocalValidatorFactoryBean realized javax.validation.ValidatorFactory and javax.validation.Validator two interfaces, as well as Spring's org.springframework.validation.Validator interfaces, you can use any of these interfaces among injecting a need to call the validation logic in the Bean.

 By default, validator LocalValidatorFactoryBean created using PlatformResourceBundleLocator obtain the binding relationship between resources, access to the resource name is: ValidationMessages

 User-defined check information on the project classpath directory.

In addition hibernate-validator will check the resource load default file name is: org.hibernate.validator.ValidationMessages. You can see, the default check resource bundle file contains configuration information for different regions.

How LocalValidatorFactoryBean acquired validator is loaded with different resource files check it according to different regions? hibernate-validator exposed a message interpolator (MessageInterpolator), spring is the re-interpolator news agency.

 By LocaleContextMessageInterpolator source, you can eventually get to see the current time zone information by LocaleContextHolder.

 

Can you customize the information resources of an international check it? Of course, yes, we just need to rewrite the process of creating LocalValidatorFactoryBean type of bean, resource information specified by setValidationMessageSource custom method.

MessageSource test

Basis test

建立Resouce bundle messages

Write message source test method, to get the current value from the request in Locale

 Write test class Locale specified value of the current request or set value header request header: Accept-Language: zh

Depending on the value of the test class Locale request, the acquired text is different.

Formatting test

建立Resouce bundle messages

Write message source test method, to get the current value from the request in Locale

 Write test class Locale specified value of the current request or set value header request header: Accept-Language: zh

 

Depending on the value of the test class Locale request acquired formatted text is different.

Static test message source

Dynamic registration Message (distinguishable Locale), it can be used to customize the message source.

The method of writing tests, accessed through MessageSourceAccessor.

 Write test classes, get a custom message source of information.

Depending on the value of the test class Locale request, the acquired text is different.

 

Guess you like

Origin www.cnblogs.com/hujunzheng/p/11037577.html