Vue+Springboot打造前后端分离的企业管理系统—Spring boot后端国际化应用支持详解

时间:2024-04-09 08:20:54

      我们的系统需要支持国际化应用,就是可以在不同的语言环境下,方便的进行切换。大家都知道,在 Spring 中国际化,也叫 i18n,为啥叫这个名字呢?因为国际化英文是 internationalization ,在 i 和 n 之间有 18 个字母,所以叫 i18n,就通过 AcceptHeaderLocaleResolver 对国际化提供了支持,我们只需要通过简单配置,就可以在项目中直接使用国际化功能了。这一支持在 Spring Boot 中得到进一步的简化,在 Spring Boot 中,我们也可以通过寥寥数行代码就能方便的实现国际化功能。
      系统要实现支持完整的国际化应用,在开发过程中需要多方面的支持,例如后端做国际化、前端页面也要做国际化,共同搭配,才能真正实现国际化的功能。本文我们先实现后端 Spring Boot服务端 的国际化,后面我再实现前端操作层的国际化(Vue 的国际化),最后把这两个结合应用到我们本次的 项目中。
      在开始进行国际化支持开发之前,我们需要做对一些事情,否则可能会出现Spring boot端信息传输到前端页面后乱码的情况。

1. 先要保证我们编辑的properties文件是用UTF-8格式编写,通过设置idea的文件编码来指定message文件的编码格式。
        打开 File -> Settings -> Editor -> File Encodings,修改相关编码格式为UTF-8,如下图:

Vue+Springboot打造前后端分离的企业管理系统—Spring boot后端国际化应用支持详解

2. 在application.properties配置文件中增加以下设置项:
        spring.messages.encoding=UTF-8
        spring.http.encoding.charset=UTF-8
        spring.http.encoding.force=true
        spring.http.encoding.enabled=true
        server.tomcat.uri-encoding=UTF-8

        完成这些准备工作后,我们就可以开始动手让我们的程序支持国际化了。Spring Boot 和 Spring 一脉相承,对于国际化的支持,默认是通过 AcceptHeaderLocaleResolver 解析器来完成的,这个解析器,默认是通过请求头的 Accept-Language 字段来判断当前请求所属的环境的,进而给出合适的响应。
        在 Spring Boot 中这一块我们可以不用配置,直接就可以动手了。默认的国际化配置文件放在 resources 目录下,所以我们直接在该目录下创建需要用到的消息文本配置文件,如下:

Vue+Springboot打造前后端分离的企业管理系统—Spring boot后端国际化应用支持详解

   • 我们的 message 文件是直接创建在 resources 目录下的,IDEA 在展示的时候,会多出一个 Resource Bundle,这个大家不用管,千万别手动去创建这个目录。
        • messages.properties 这个是默认的配置,其他的则是不同语言环境下的配置,en_US 是英语(美国),zh_CN 是中文简体等等。
        如简体中文的messages_zh_CN.properties:
        USER_DISABLED=用户已被禁用!
        USERNAME_OR_PASSWORD_ERROR=用户名或密码错误!
        USERNAME_OR_PASSWORD_NOTALLOW_EMPTY=用户名或密码不能为空!
        USERNAME_OCCUPIED=用户名已被占用!

        英文messages_en_US.properties:
        USER_DISABLED=The user already disabled.
        USERNAME_OR_PASSWORD_ERROR=The user name or password was error.
        USERNAME_OR_PASSWORD_NOTALLOW_EMPTY=The user name or password not allowe mpty.
        USERNAME_OCCUPIED=The user name was occupied

        配置完成后,我们就可以直接开始使用了。在需要使用值的地方,直接注入 MessageSource 实例即可,如:
        Useruser=userService.findByUsername(username);
        if(!user.getEnabled()){
           Stringmessage=messageSource.getMessage("USER_DISABLED",null,LocaleContextHolder.getLocale());

           returnResultFactory.buildFailResult(message);
        }

        默认情况下,Spring boot在接口调用时通过请求头的 Accept-Language 来配置当前的语言环境,不是很方便,我们可以通过自定义解析方式。把语言环境参数可以当成普通参数放在地址栏上。通过项目启动配置类中增加如下配置可以实现这个需求。
        @Override
        publicvoidaddInterceptors(InterceptorRegistryregistry) {
             LocaleChangeInterceptorinterceptor=newLocaleChangeInterceptor();
             interceptor.setParamName("lang");
             registry.addInterceptor(interceptor);
        }

        @Bean
        LocaleResolverlocaleResolver() {
            SessionLocaleResolverlocaleResolver=newSessionLocaleResolver();
            localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);

            returnlocaleResolver;
        }
        在这段配置中,我们首先提供了一个 SessionLocaleResolver 实例,这个实例会替换掉默认的 AcceptHeaderLocaleResolver,不同于 AcceptHeaderLocaleResolver 通过请求头来判断当前的环境信息,SessionLocaleResolver 将客户端的 Locale 保存到 HttpSession 对象中,并且可以进行修改(这意味着当前环境信息,前端给浏览器发送一次即可记住,只要 session 有效,浏览器就不必再次告诉服务端当前的环境信息)。
        另外我们还配置了一个拦截器,这个拦截器会拦截请求中 key 为 lang 的参数(不配置的话是 locale),这个参数则指定了当前的环境信息。
        配置完成后,启动项目,访问方式如下:

Vue+Springboot打造前后端分离的企业管理系统—Spring boot后端国际化应用支持详解

 我们通过在请求中添加 lang 来指定当前环境信息。这个指定只需要一次即可,也就是说,在 session 不变的情况下,下次请求可以不必带上 lang 参数,服务端已经知道当前的环境信息了。
        到此为止,我们已经完成了Spring boot后端的国际化支持的开发,可以愉快地进行多语言支持了。但需要注意的是,系统可能会出现从后端的中文信息传回到前端的时候变成了乱码了,如果我们在application.properties中已经增加了UTF-8字符编码的设置,但仍然无法解决时,我们需要直接干预消息转换器来解决这个问题。
        Spring Boot底层通过HttpMessageConverters依靠Jackson库将Java实体类输出为JSON格式。当有多个转换器可用时,根据消息对象类型和需要的内容类型选择最适合的转换器使用。

       消息转换器的目标是:HTTP输入请求格式向Java对象的转换;Java对象向HTTP输出请求的转换。有的消息转换器只支持多个数据类型,有的只支持多个输出格式,还有的两者兼备。例如:MappingJackson2HttpMessageConverter可以将Java对象转换为application/json,而ProtobufHttpMessageConverter仅支持com.google.protobuf.Message类型的输入,但是可以输出application/json、application/xml、text/plain和application/x-protobuf这么多格式。
       StringHttpMessageConverter是一个请求和响应信息的编码转换器,通过解读它的源码我们发现默认编码ISO-8859-1,不是UTF-8,所以我们只要通过上述配置将请求字符串转为UTF-8 即可

Vue+Springboot打造前后端分离的企业管理系统—Spring boot后端国际化应用支持详解

在Web启动配置类中重写信息编码转换器,如下:
@Override
publicvoidconfigureMessageConverters(List<HttpMessageConverter<?>>converters) {
converters.add(responseBodyConverter());
}
//这个为解决中文乱码
@Bean
publicHttpMessageConverter<String>responseBodyConverter() {
StringHttpMessageConverterconverter=newStringHttpMessageConverter(
Charset.forName("UTF-8"));
returnconverter;
}

如以上代码,将信息编码修改为UTF-8后即可解决前端乱码问题,现在可以愉快地让系统支持国际化应用啦。