1)、编写国际化配置文件;

2)、使用ResourceBundleMessageSource管理国际化资源文件

3)、在页面使用fmt:message取出国际化内容

步骤
1)、编写国际化配置文件,抽取页面需要显示的国际化消息

国际化文件是peroperties文件  

 自动识别国际化视图

通过国际化视图创建国际化配置文件

 同时对比编辑多个配置文件

 配置国际化文件路径:

spring.messages.basename=static.i18n.login
@Configuration
@ConditionalOnMissingBean(
value = {MessageSource.class},
search = SearchStrategy.CURRENT
)
@AutoConfigureOrder(-2147483648)
@Conditional({MessageSourceAutoConfiguration.ResourceBundleCondition.class})
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0]; public MessageSourceAutoConfiguration() {
} @Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
} @Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
       //设置国际化文件的基础名称(去掉语言_国家代{zh_CN})的):即默认是message.properties,上图中我们起的名称是login.properties
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
} if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
} messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
} messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
} protected static class ResourceBundleCondition extends SpringBootCondition {
private static ConcurrentReferenceHashMap<String, ConditionOutcome> cache = new ConcurrentReferenceHashMap(); protected ResourceBundleCondition() {
} public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
       //自定义的话就用此属性:spring.messages.basename来指定,默认叫message.propertie
       //我们上图的需要指定为:spring.messages.basename=login
String basename
= context.getEnvironment().getProperty("spring.messages.basename", "messages");
ConditionOutcome outcome = (ConditionOutcome)cache.get(basename);
if (outcome == null) {
outcome = this.getMatchOutcomeForBasename(context, basename);
cache.put(basename, outcome);
} return outcome;
} private ConditionOutcome getMatchOutcomeForBasename(ConditionContext context, String basename) {
Builder message = ConditionMessage.forCondition("ResourceBundle", new Object[0]);
String[] var4 = StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(basename));
int var5 = var4.length; for(int var6 = 0; var6 < var5; ++var6) {
String name = var4[var6];
Resource[] var8 = this.getResources(context.getClassLoader(), name);//类路径
int var9 = var8.length; for(int var10 = 0; var10 < var9; ++var10) {
Resource resource = var8[var10];
if (resource.exists()) {
return ConditionOutcome.match(message.found("bundle").items(new Object[]{resource}));
}
}
} return ConditionOutcome.noMatch(message.didNotFind("bundle with basename " + basename).atAll());
} private Resource[] getResources(ClassLoader classLoader, String name) {
String target = name.replace('.', '/'); try {
          //类路径下的 message.properties 和 messages_zh_CN.properties 或 自己指定的xxxx.properties 、xxxx.preperties
return (new PathMatchingResourcePatternResolver(classLoader)).getResources("classpath*:" + target + ".properties");
} catch (Exception var5) {
return MessageSourceAutoConfiguration.NO_RESOURCES;
}
}
}
}
public class MessageSourceProperties {
private String basename = "messages";//我们的配置文件可以直接放在类路径下,默认名称叫message.properties
private Charset encoding;
@DurationUnit(ChronoUnit.SECONDS)
private Duration cacheDuration;
private boolean fallbackToSystemLocale;
private boolean alwaysUseMessageFormat;
private boolean useCodeAsDefaultMessage; public MessageSourceProperties() {
this.encoding = StandardCharsets.UTF_8;
this.fallbackToSystemLocale = true;
this.alwaysUseMessageFormat = false;
this.useCodeAsDefaultMessage = false;
} public String getBasename() {
return this.basename;
} public void setBasename(String basename) {
this.basename = basename;
}
......
}

<!-- 中英文切换链接 -->

<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN'}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>

是根据浏览器的默认语言识别的

 不过取出来的中文有乱码

 IDEA中将UTF-8自动组转为ASSIC码

  

File   ——》 settings 里的设置只是针对当前项目的设置,要想设置全局的

 

 Settins  ——》Other Settings ——》Default Settings  设置全局的默认设置

然后重新编辑有乱码的properties文件

 根据浏览器的默认语言设置自动区分国际化字段的显示

默认请求头里会有语言的信息

切换默认的语言,请求头中排在第一位的也就变了

实现原理:

国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象)

public class WebMvcAutoConfiguration {
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware { @Bean
@ConditionalOnMissingBean //当项目中没有区域解析器的时候,才执行这个SprigBoot默认的配置,所以可以自定义
@ConditionalOnProperty(
prefix = "spring.mvc",
name = {"locale"}
)
//
public LocaleResolver localeResolver() { //默认从配置文件中获取
if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
} else {//如果配置文件中没有,则从HttpRequest的header中获取
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
} } public class AcceptHeaderLocaleResolver implements LocaleResolver { public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = this.getDefaultLocale();
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
} else {
Locale requestLocale = request.getLocale();
List<Locale> supportedLocales = this.getSupportedLocales();
if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
if (supportedLocale != null) {
return supportedLocale;
} else {//如果默认的区域解析器为空,则从requset请求头中获取
return defaultLocale != null ? defaultLocale : requestLocale;
}
} else {
return requestLocale;
}
}
} }

自定义区域解析器,点击链接切换国际化

public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String l = request.getParameter("l");
Locale locale = Locale.getDefault();
if (!StringUtils.isEmpty(l)) {
String[] split = l.split("_");
locale = new Locale(split[0], split[1]);
}
return locale;
} @Override
public void setLocale(HttpServletRequest httpServletRequest, @Nullable HttpServletResponse httpServletResponse, @Nullable Locale locale) { }
}
//将自定义的区域解析器加入到容器中来
@Bean     
public LocaleResolver localeResolver(){         
return new MyLocaleResolver();     
}

12. SpringBoot国际化的更多相关文章

  1. SpringBoot 国际化配置,SpringBoot Locale 国际化

    SpringBoot 国际化配置,SpringBoot Locale 国际化 ================================ ©Copyright 蕃薯耀 2018年3月27日 ht ...

  2. springboot国际化与@valid国际化支持

    springboot国际化 springboot对国际化的支持还是很好的,要实现国际化还简单.主要流程是通过配置springboot的LocaleResolver解析器,当请求打到springboot ...

  3. 【spring 国际化】springMVC、springboot国际化处理详解

    在web开发中我们常常会遇到国际化语言处理问题,那么如何来做到国际化呢? 你能get的知识点? 使用springgmvc与thymeleaf进行国际化处理. 使用springgmvc与jsp进行国际化 ...

  4. SpringBoot 国际化

    一.配置文件 二.application.properties 文件( 让国际化的文件被 SpringBoot 识别 ) spring.messages.basename=i18n.login 三.h ...

  5. 12.SpringBoot+MyBatis(XML)+Druid

    转自:https://www.cnblogs.com/MaxElephant/p/8108342.html 主要是在Spring Boot中集成MyBatis,可以选用基于注解的方式,也可以选择xml ...

  6. Springboot国际化信息(i18n)解析

    国际化信息理解 国际化信息也称为本地化信息 . Java 通过 java.util.Locale 类来表示本地化对象,它通过 “语言类型” 和 “国家/地区” 来创建一个确定的本地化对象 .举个例子吧 ...

  7. 补习系列(12)-springboot 与邮件发送【华为云技术分享】

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...

  8. 【SpringBoot】SpringBoot 国际化(七)

    本周介绍SpringBoot项目的国际化是如何处理的,阅读本章前请阅读[SpringBoot]SpringBoot与Thymeleaf模版(六)的相关内容 国际化原理 1.在Spring中有国际化Lo ...

  9. 补习系列(12)-springboot 与邮件发送

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...

随机推荐

  1. node.js依赖express解析post请求四种数据格式()

    分别是这四种: www-form-urlencoded, form-data, application/json, text/xml www-form-urlencoded 这是http的post请求 ...

  2. sort和uniq的应用实例

    sort 排序 uniq 1.语法:sort [option]... [file]... 2.选项:-k key,关键子,指定以那个列来排序.如果不指定,默认将正行作为关键字排序-n 对数值排序.默认 ...

  3. html 统一资源定位器(url)和url编码

    url,即统一资源定位器,也叫网址. 点击<a>标签就会连接到url指定的服务器web资源,文档或者其它数据: url的命名规则:url可是域名或者IP地址 url="shcem ...

  4. matplotlib之scatter绘制散点

    # 使用matplotlib.pyplot.scatter绘制散点 import matplotlib.pyplot as plt from pylab import mpl # 设置默认字体,解决中 ...

  5. CSS变形transform(2d)

    前面的话 CSS变形transform是一些效果的集合,主要是移动.旋转.缩放和倾斜这四种基本操作,还可以通过设置matrix矩阵来实现更复杂的效果.变形transform可以实现2D和3D两种效果. ...

  6. 优步加入Linux基金会:支持开源

    导读 当地时间11月16日,优步在Uber Open Summit 2018年度峰会上宣布加入Linux基金会,并作为金级会员坚定支持对开源工具的使用和贡献. 优步CEO Thuan Pham将Lin ...

  7. Tree 菜单 递归

    转载:http://www.cnblogs.com/igoogleyou/archive/2012/12/17/treeview2.html 一,通过查询数据库的方法 ID 为主键,PID 表明数据之 ...

  8. 码云平台IDEA系列的插件使用

    一.IDEA插件安装 file -- setting --  Plugins -- 搜索gitee --  Search in repositories 安装后重启编译器 二.登录并拉取项目 file ...

  9. 学习Spring Boot:(二十三)Spring Boot 中使用 Docker

    前言 简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建,发布一个镜像,现在我们通过远程的 docker api 构建镜像,运行容器,发布镜像等操作. 这里只介绍两种方式: 远 ...

  10. 【BZOJ2003】[HNOI2010]矩阵(搜索)

    [BZOJ2003][HNOI2010]矩阵(搜索) 题面 懒得粘了,不难找吧. 题解 看的学长写的题解,也懒得写了 大概是这样的. 不难发现只需要确定第一行和第一列就能确定答案,而确定第一行之后每确 ...