zoukankan      html  css  js  c++  java
  • 21. SpringBoot 实现国际化 [i18n]

    如果我们在SoringMVC 写国际化 ,那么肯定是 编写国际化配置文件 然后 使用ResourceBundleMessageSource管理国际化资源文件 ,在JSP页面使用fmt:message取出国际化内容.

     我们的目标是把上面国际化

    现在用SpringBoot写,我们先写 国际化配置文件properties ,,,SpringBoot 很方便写:

    在response文件夹下新建 i18n,我们在里面写吧,新建3个文件:  【记住!!! properties编码要改变!  不然前功尽弃!】

    我们第一个做为默认  第二个 是en_US  美国 表示英语  ,第三个 zh_CN 表示中国。   【这里login 和 国家区域代码  是用  _  分开的。 】

    当SpringBoot 会自动识别出 国家区域代码 然后可以很方便的 Add 添加。

    点击 Resoucre Bundle 可以快速编辑   这里自己来吧! 

    编辑好之后 即可。



    SpringBoot 自动配置好了管理国际化资源文件的组件,我们查找看下主要源码 然后才知道怎么配置:

    搜一下 MessageSourceAutoConfiguration 自动配置文件  可以看到里面配置:

    主要配置1: MessageSourceAutoConfiguration 自动配置中特性:
    
    
    /**
    * Comma‐separated list of basenames (essentially a fully‐qualified classpath
    * location), each following the ResourceBundle convention with relaxed support for
    * slash based locations. If it doesn't contain a package qualifier (such as
    * "org.mypackage"), it will be resolved from the classpath root.
    *  这个注释说的是 如果你要使用你自己的国际化配置文件properties,那么你就得在配置文件中设置,如果没设置任何指定【指定的时候注意基础名】,
    * 那么他就自动在resouce中寻找!
    */ public class MessageSourceAutoConfiguration { private static final Resource[] NO_RESOURCES = new Resource[0]; private String basename = "messages";    //我们的配置文件可以直接放在类路径下叫messages.properties,他会自动读取。
    ////主要配置2 :添加了个组件进入,其中这里设置的是 基础名,结合上面 一起配置国际化功能
    @Bean
        public MessageSource messageSource() {
            //全称
            ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
            if (StringUtils.hasText(this.basename)) {
                //这里是设置国际化文件的基础名(就是_和国家区域代码分开的前一个 比如我们的 login_zh_CN 基础名就是login) 他这里默认就是message了,所以他会自动去找message....
                messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(this.basename)));
            }
    
            if (this.encoding != null) {
                messageSource.setDefaultEncoding(this.encoding.name());
            }
    
            messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
            messageSource.setCacheSeconds(this.cacheSeconds);
            messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
            return messageSource;
        }

    所以我们现在去 配置文件中 配置下 基础名:



    最后在HTML 直接用Thynelemaf模板代码 #{...}:进行获取国际化内容:(确保你配置了Thymeleaf!和 properties的编码 不然出现乱码!) 如果都配置了 还是乱码,那么你看你html文件缺少默认编码头meta (<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>)没。

    index.html(登录)的代码在这  寻找国际化数据源的代码里面都注释已标出!:

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
        <title>Signin Template for Bootstrap</title>
        <!-- Bootstrap core CSS -->
        <!-- @{} 这个是 根路径 servlet 的 getCountextPath 那个差不多 -->
        <link href="asserts/css/bootstrap.min.css" rel="stylesheet" th:href="@{/webjars/bootstrap/4.0.0/dist/css/bootstrap.css}" />
        <!-- Custom styles for this template -->
        <link href="asserts/css/signin.css" rel="stylesheet" th:href="@{/asserts/css/signin.css}" />
    </head>
    
    <body class="text-center">
    <form class="form-signin" action="dashboard.html">
        <img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
        <!--  这一个 直接用th:text 配合  #{...}进行取出国际化数据  -->
        <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.title}">Please sign in</h1>
        <label class="sr-only" >Username</label>
        <!--  这一个 直接用th:text 配合  #{...}进行取出国际化数据  -->
        <input type="text" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus="">
        <label class="sr-only" th:text="#{login.passwprd}" >Password</label>
        <!--  这一个 直接用th:text 配合  #{...}进行取出国际化数据  -->
        <input type="password" class="form-control" th:placeholder="#{login.passwprd}" placeholder="Password" required="">
        <div class="checkbox mb-3">
            <label>
                <!--  这一个 因为是行内 所以用行内标签解析  + #{...}取出  -->
                <input type="checkbox" value="remember-me"> [[#{login.Remember}]]
            </label>
        </div>
        <!--  这一个 直接用th:text 配合  #{...}进行取出国际化数据  -->
        <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.sign}" >Sign in</button>
        <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
        <a class="btn btn-sm">中文</a>
        <a class="btn btn-sm">English</a>
    </form>
    
    </body>
    
    </html>
    index.html

     然后运行 打开浏览器 把语言设置成中文 ,然后就是中文的了:

     

     如果设置英文:



    那么他的原理就是根据国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象);但我们想通过 链接来切换,那么就要:

    WebMvcAutoConfiguration 里面配置了  LocaleResolver ,看下他代码即可:

     @Bean
            @ConditionalOnMissingBean
            @ConditionalOnProperty(
                prefix = "spring.mvc",
                name = {"locale"}
            )
            public LocaleResolver localeResolver() {
                if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.WebMvcProperties.LocaleResolver.FIXED) {
                    return new FixedLocaleResolver(this.mvcProperties.getLocale());
                } else {
                    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
                    localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
                    return localeResolver;
                }
            }

    所以可以看出 他默认的就是根据请求头带来的区域信息获取Locale进行国际化,⭐⭐⭐⭐而且看下@ConditionalOnMissingBean这个注解 说明没 localeResolver 这个组件的时候 默认配置才生效,那么我们自定义一个,这里注意 自定义时 加入组件的ID 一定要是 localeResolver(方法名)  因为注解只判断 这个 localeResolver 是否存在决定默认生效否。那么我们思路就可以是:

    首先写连接请求 可以携带参数(区域码):

    然后自己配置一个 localeResolver :

    package com.bihu.component;
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.servlet.LocaleResolver;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Locale;
    
    /*自己定义一个 LocaleResolver解析器,要实现 LocaleResolver 接口*/
    public class MyLocaleResolver implements LocaleResolver {
    
        @Override
        public Locale resolveLocale(HttpServletRequest httpServletRequest) {
            String l = httpServletRequest.getParameter("l");
            Locale locale = Locale.getDefault();    //如果获取的参数为空 那么获取默认区域代码
            if ( l != null && !l.isEmpty()){  //参数不是null 且 长度不为空
                String[] c = l.split("_");  //分隔后 第一个是语言代码  第二个是国家代码
                locale = new Locale(c[0],c[1]);     //请求参数不是空 locale更新。
            }
            return locale;  //返回Locale对象
        }
    
        @Override
        public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    
        }
    }
    MyLocaleResolver

    最后把自己写的localeResolve加入到组件中生效:

    package com.bihu.config;
    
    import com.bihu.component.MyLocaleResolver;
    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.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    
    @Configuration
    public class mConfig extends WebMvcConfigurerAdapter {
        @Bean
        //因为全部的 WebMvcConfigurerAdapter 会一起用 所以这里加入组件即可。
        public WebMvcConfigurerAdapter addView(){
            WebMvcConfigurerAdapter webMvcConfigurerAdapter = new WebMvcConfigurerAdapter(){
                @Override
                public void addViewControllers(ViewControllerRegistry registry) {
                    registry.addViewController("/").setViewName("index");
                    registry.addViewController("/index").setViewName("index");
                }
            };
            return webMvcConfigurerAdapter;
        }
    
    ================================
        上面那个别看 下面这个才是!
        //把自己的区域解析器 加入到 自动配置中 ,注意组件ID一定要是localeResolver 因为生效否决定在@ConditionalOnMissingBean注解。
        @Bean
        public LocaleResolver localeResolver(){
            return new MyLocaleResolver();
        }
    
    }
    mConfig

    然后运行:

    可以发现成功了...

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/15126230.html

  • 相关阅读:
    linux下实现在程序运行时的函数替换(热补丁)【转】
    进程的切换和系统的一般执行过程【转】
    linux 系统函数之 (dirname, basename)【转】
    PHP的ob_start()函数用法
    JavaScript闭包(Closure)学习笔记
    利用PHP的register_shutdown_function来记录PHP的输出日志,模拟析构函数
    PHP get_class_methods函数用法
    PHP中的魔术方法:__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toString, __set_state, __clone and __autoload
    PHP get_class 返回对象的类名
    利用session_set_save_handler()函数将session保存到MySQL数据库中
  • 原文地址:https://www.cnblogs.com/bi-hu/p/15126230.html
Copyright © 2011-2022 走看看