Spring Boot实践--实现国际化

Spring boot 实现国际化

Spring目前提供了两个MessageSource的实现:ResourceBundleMessageSourceStaticMessageSource。它们都继承NestingMessageSource以便能够处理嵌套的消息。StaticMessageSource很少被使用,但能以编程的方式向消息源添加消息。ResourceBundleMessageSource会用得更多一些,为此提供了一下示例:

1:添加配置类

import java.util.Locale;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

//WebMvcConfigurerAdapter
@Configuration
public class I18nConfig extends WebMvcConfigurerAdapter {
     @Bean  
        public LocaleResolver localeResolver() {  
            SessionLocaleResolver slr = new SessionLocaleResolver();  
            slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);  
            return slr;  
        }  

        @Bean  
        public LocaleChangeInterceptor localeChangeInterceptor() {  
            LocaleChangeInterceptor lci = new LocaleChangeInterceptor();  
            lci.setParamName("lang");  
            return lci;  
        }  

        @Override  
        public void addInterceptors(InterceptorRegistry registry) {  
            registry.addInterceptor(localeChangeInterceptor());  
        }  

}

2:添加资源文件 
默认读取路径在resources下: 
可在application.properties中添加属性设置 :

#i18n configuation
spring.messages.basename=i18n/messages

效果如下图: 
这里写图片描述

messages.properties是默认访问资源

3:网页切换语言 
于url上拼接属性 如下

?lang=en_US

该属性会存于cookie中,网页跳转将继续使用该语言:

Cookie:JSESSIONID=9EFE46F94D0F89A9E7FBD1073631DEC5; hudson_auto_refresh=false; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=d3A3NzE5MTAwMTI6MTQ4MjczNzMxNjkxMjpkZDQ2MzM2NTc3ZmM3ZjU1Y2UzYjk2YWU2NjkwNjlmMjNmMjQwMDhhZmRlOGQxOWQ0YzRjOTM4ZTAwNzYwZmM5; jenkins-timestamper-offset=-28800000; org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=en_US

最后一行即为存于cookie中的 语言属性

4:controller层中语言属性

LocaleContextHolder.getLocale()

可获取Locale类 
可用如下代码进行语言判断:

LocaleContextHolder.getLocale().equals(Locale.US)

如有意见 请于评论指出 谢谢~

 

相关文章:

58. Spring Boot国际化(i18n)【从零开始学Spring Boot】

使用自定义的MessageSource实现对properties的复用

spring通过ResourceBundleMessageSource实现国际化

 

实现国际化:

一:消息无参

lang_zh.properties内容,name=\u5F20\u4E09 

lang_en.properties内容,name=zhangsan

注意:配置文件的命名需要带上语言种类的即:文件名_语言种类.properties,并且不同语言的相同消息的文件名应该一样,例如ang_zh.properties和lang_en.properties就表示中文和英语

语言种类不知道该怎么写的可以在程序中输出,System.out.println(Locale.CHINESE);即可

接着我们就是在spring配置文件中配置:

    <bean id="messageSource"
          class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>config/properties/lang</value>
            </list>
        </property>
    </bean>

 这里需要注意几点:

①在basenames中输入的相对路径

②文件不需要文件类型比如:我的语言文件是lang_zh.properties和lang_en.properties在这里我就只需要输入lang

③大家也看到了,不同语言的文件不需要全部都导入,只需要写文件名即可,看我的配置就知道了

最后就是应用了,

在程序中我们需要得到spring中配置的这个bean,可以通过注入,也可以通过beanUtil获取,我的代码如下:

Java代码 

MessageSource ms = (MessageSource) BeanUtil.getBeanByName("configProperties") ; 
System.out.println(ms.getMessage("name",new Object[]{} , Locale.CHINESE));  //张三
System.out.println(ms.getMessage("name",new Object[]{} , Locale.ENGLISH));  //zhangsan

 

在这里的ms.getMessage中有两个三个方法,我只研究了三个参数的和四个参数的getMessage(String arg0, Object[] arg1, Locale arg2) 这里, 第一个参数是文件中的字段名,第二个参数是文件中占位符的参数(后面讲),第三个参数是语言种类,可以通过Locale.种类获取

getMessage(String arg0, Object[] arg1, String arg2, Locale arg3)这里第一个参数是文件中的字段名,第二个参数是文件中占位符的参数(后面讲),第三个参数是默认值,第四个参数是语言种类,可以通过Locale.种类获取

这里需要注意的是,如果没有占位符也可以用null

二:消息中带参数

那么我需要在文件中带入占位符,如我吧语言文件中的内容改为:

lang_zh.properties内容,name=\u5F20\u4E09 {0}

lang_en.properties内容,name=zhangsan{0}
MessageSource ms = (MessageSource) BeanUtil.getBeanByName("configProperties") ; 
​
System.out.println(ms.getMessage("name",new Object[]{} , Locale.CHINESE));   //张三
System.out.println(ms.getMessage("name",new Object[]{"年龄:20"} , Locale.CHINESE));   //张三年龄20


System.out.println(ms.getMessage("name",new Object[]{} , Locale.ENGLISH));  //zhangsan
System.out.println(ms.getMessage("name",new Object[]{"age:20"} , Locale.ENGLISH)); //zhangsanage20


如果你的文件中的消息有占位符,同时又有单引号就需要注意了,有占位符的时候,单引号需要转义,只需要在单引号前再加一个单引号就可以了,

例如:

name='dengwei'{0}

我就需要写成:name=''dengwei‘’{0}记得是两个单引号,而不是双引号

更多信息:占位符和信息格式化:

实现品牌内容:

而在我们的项目中有这样一个需求。假设现在项目中有三个properties文件。

其中aami和apia是我们项目需要支持的两个品牌。当一个用户登陆我们的web项目时,会自动将其当前所使用的品牌信息存到session中。而如果是aami用户的话,前端jsp页面显示的message读取的顺序是这样的:如果在aami.properties文件中没找到的话,就在default.properties文件中找。对于apia用户,则先在apia.properties中找,然后查找default.properties。

举个例子,如果default.properties中有一个键值对helloWorld.label = Welcome。那么在jsp上使用时会显示Welcome。但是对于ammi来说需要用同样的键hello.world.label但是显示Welcome to AAMI

这样可以最大程度的复用default.properties中的数据,同时又可以根据自身品牌定义一些自身的数据在自身品牌的properties文件中。

ResourceBundleMessageSource中有一个parentMessageSource属性,如果在当前MessageSource中找不到code的值,会在parentMessageSource中查找。一个简单的配置如下。

    <bean id="messageSource"
          class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="parentMessageSource">
            <bean class="org.springframework.context.support.ResourceBundleMessageSource">
                <property name="basename">
                    <value>default</value>
                </property>
            </bean>
        </property>
        <property name="basenames">
            <list>
                <value>aami</value>
            </list>
        </property>
    </bean>

 

如果给给定一个code,程序会先在aami.properties文件中查找,如果未找到,则会在default中查找。 这似乎能满足我们的要求。其实不行。假如我们现在将apia品牌也加入,如果想让程序根据当前用户的品牌来选择适合的properties做成首选,当前这个功能是不满足的。我们需要自定义一个继承自ResourceBundleMessageSource的类来实现。

 

 

 

转载于:https://my.oschina.net/spinachgit/blog/1813285

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值