springBoot国际化的一种方式

news2024/11/17 16:40:53

引言:

        当我们的应用面向不同国家用户时,根据不同的locale返回不同的语言信息的国际化功能就显得有必要了。一般来说国际化主要表现在前端用户界面上,在现在前后端分离的背景下,前端页面的国际化交由前端代码独立完成;少部分表现在后端上,后端主要表现在一些固定的信息的国际化,比如异常提示信息。但无论是前端还是后端,所要制作国际化的部分都是程序中固定不变的、非用户填写信息

 好了,废话少说,开整。

本次所实现的功能有两种:

1)根据key直接翻译

2)springValidator校验信息的国际化

3)javax的validator国际化(暂时不会)

功能实现的两个核心逻辑点:1、获取客户端语言 2、根据语言到不同的文件查找数据

一、根据key直接翻译

1、实现 LocaleResolver接口并重写resolveLocale方法

类似代码如下:

/**
 * TestLocaleResolver
 * <p>
 *  自定义localResolver解析客户端的locale。
 *  这里是采用类扫描的形式,也可以使用@Bean配置一个对象,但名字也必须是localResolver
 * </p>
 */
@Slf4j
@Component(value = "localeResolver")
public class TestLocaleResolver implements LocaleResolver {


    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        try {
            final String acceptLanguage = request.getHeader("Accept-Language2");
            if (StringUtils.isEmpty(acceptLanguage)){
                return Locale.getDefault();
            }
            String language = acceptLanguage.split(",")[0];
            final String[] split = language.split("-");

            return new Locale(split[0],split[1]);
        }catch (Exception e){
            log.error(e.getMessage());
            return Locale.getDefault();
        }

    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}

注意:为了避免springBoot自动配置localResolver,bean的名称必须是 localeResolver

之后就可以使用  LocaleContextHolder.getLocale()   获取到刚才设置的 Locale对象。

2、设置国家化资源文件

默认是类路径下的 messages.properties文件,可以通过spring提供的配置自定义文件位置,如下

#国际化文件位置
spring:
  messages:
    basename: i18n/message

然后在设置的类路径下书写不同语言的文件了,如下所示:

 message.properties是默认的文件,当客户端语言无法匹配时从这里获取。

message_zh_CN.properties

error.noUser=用户不存在!
error.params=参数{0}不能为空!
userConfig.module=所属模块不能为空!

message_en_US.properties

error.noUser=user not exist!
error.params=param {0} can't be null!
userConfig.module=belong module can't be null!

有Locale了,有国际化资源文件了,怎么根据语言获取配置的数据呢?

        如果要自己写的话可能就要写个方法,接收语言和key参数,然后判断从不同的语言文件中获取对应的变量数据。对于.properties文件java也提供Properties类方便读写,为了性能还要把.properties文件的内容读取到内存中。

        但是spring也想到了这一点,给我们提供了一个 MessageSource接口(在I18n中其实现类是ResourceBundleMessageSource,并且实现了其自动配置,我们可以直接注入MessageSource然后调用他的方法即可,例如:

public String getMessage(String key){
    return messageSource.getMessage(key,null,LocaleContextHolder.getLocale());
}

2、springValidator校验信息的国际化

1、设置用来校验的validator

    @Autowired
    private MessageSource messageSource;

    /**
     * spring用来国际化的validator
     * ps:javax的validator
     * @return
     */
    @Bean
    public Validator validator() {
        LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
        // 设置validator的资源文件管理者
        validator.setValidationMessageSource(messageSource);
        return validator;
    }

2、bean的校验message设置成变量的形式

@NotEmpty(message = "{userConfig.module}",groups = {AddCheck.class)
@TableField(value = "module")
private String module;

3、controller入参添加spring的@Validated注解

 @PostMapping("/test2")
    public ResultVO<Object> test2(@Validated(AddCheck.class) PersonManage personManage){

        return Result.success();
    }

工作过程是:

        当该方法被执行时,springMVC会执行上面的TestLocaleResolver 的resolveLocale方法解析出当前请求的Locale,然后根据bean属性的message的变量名,调用 ResourceBundleMessageSource 的方法从对应的语言文件中解析出变量值,然后抛出一个 MethodArgumentNotValidException异常,我们可以用SpringMVC的异常处理器,解析异常并按照统一的格式返回,异常处理器如下:

   /**
     * 处理bean的验证异常信息
     */
    @ExceptionHandler({
            BindException.class,
            MethodArgumentNotValidException.class,
    })
    public ResultVO<Map<String, String>> handleBindException(Exception ex) {
        BindingResult result = null;
        if (ex instanceof BindException){
            BindException exception = (BindException) ex;
            result = exception.getBindingResult();
        }else {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            result = exception.getBindingResult();
        }

        Map<String, String> errorInfoMap= new HashMap<>();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            for (ObjectError error : errors) {
                FieldError fieldError = (FieldError) error;
                errorInfoMap.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
        }
        return Result.error(ErrorStatus.PARAM_VALIDATE_FAIL, errorInfoMap);
    }

总结:

        涉及的东西有SpringMVC的localResolver组件、MessageSource接口、spring的Validator接口,总之搞清楚所使用的的框架还是很有用的,搞清楚之后,这些代码就是你的小兵了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

只用两行代码做个表白二维码,赶快送给你心目中那个她吧♥(๑> ₃ <)♥

上一篇&#xff1a;教你一招完美解决 pptx 库安装失败的问题 今天有同事给我说&#xff1a;女朋友生日快到了&#xff0c;想用Python给她写个表白二维码&#xff0c;然后印在买的衣服上送给她。这么特别的生日礼物&#xff0c;博主还是第一次听到&#xff0c;不得不说&#xff…

Linux-make/Makefile

一、了解make/Makefile对于make/Makefile首先我们需要了解make是一条命令&#xff1b;Makefile是一个文件。make是一个命令&#xff0c;可以执行某条指令。这个我们理解&#xff0c;那Makefile是一个文件&#xff0c;那这个文件是干什么用的呢&#xff1f;这个文件内部一共包含…

SAP中新增销售科目配置分析实例

公司有一批呆滞维修用备件需要卖出&#xff0c;对应在系统内就需要做销售处理。但通常情况下&#xff0c;系统设计时没有考虑和配置备件销信也很正常。所以&#xff0c;处理时可能因为缺少配置做不下去。我需要解决配置问题&#xff0c;并做下可行性的测试。 首先考虑到的是末…

UniRx之ReactiveCommand

前言 UniRx中ReactiveCommand和AsyncReactiveCommand是一种基于IObservable的可控命令机制&#xff0c;用于控制是否允许进程运行 很难用文字说明&#xff0c;下面我们直接看代码吧 ReactiveCommand void Start() {//创建IObservable<bool>ReactiveProperty<bool&g…

分布式事务2种协议 及 4种模式

分布式事务协议 解决分布式事务&#xff0c;也有相应的规范和协议。分布式事务相关的协议有2PC、3PC。 由于三阶段提交协议3PC非常难实现&#xff0c;目前市面主流的分布式事务解决方案都是2PC协议。 2PC&#xff1a;两阶段提交协议 两阶段提交协议&#xff1a;事务管理器分…

如何为客户创建一个简单好用的帮助文档?

产品售后服务难&#xff0c;客服人员压力大&#xff0c;客户不满意。相信这是很多企业都面临的问题&#xff0c;产品是卖出去了&#xff0c;但是做不完的售后&#xff0c;回答不完的重复问题&#xff0c;电话、微信响个不停&#xff0c;售后服务一直都是企业的一个痛点&#xf…

JSR303数据校验和@ControllerAdvice统一异常处理

1.引入依赖&#xff08;springboot2.3之后需要引入&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>2.6.6</version> </dependency>…

scrapy总结

一、scrapy是什么&#xff1f;*结构性数据&#xff1a;即同一类型的数据如&#xff1a;某一网页上的同一类型的标签二、scrapy安装pip install scrapy出错提示to update pip&#xff0c;请升级pippython -m pip install --upgrade pip三、scrapy的基本使用&#xff08;爬虫项目…

Python __del__()方法:销毁对象

Python 通过调用 __init__() 方法构造当前类的实例化对象&#xff0c;而本节要学的 __del__() 方法&#xff0c;功能正好和 __init__() 相反&#xff0c;其用来销毁实例化对象。事实上在编写程序时&#xff0c;如果之前创建的类实例化对象后续不再使用&#xff0c;最好在适当位…

Python爬虫-某懂车平台之汽车销量排行榜

前言 本文是该专栏的第33篇,后面会持续分享python爬虫干货知识,记得关注。 之前笔者在本专栏有详细介绍过该平台二手车数据,感兴趣的同学可以在本专栏往前翻阅查找。而本文要介绍的内容,是汽车销量排行数据。 地址:aHR0cHM6Ly93d3cuZG9uZ2NoZWRpLmNvbS9zYWxlcw== (注:地…

哪个牌子台灯对孩子视力好?精选不同价位的学生护眼台灯

在我国&#xff0c;由于科技水平的提高和电子产品的普及&#xff0c;儿童青少年的近视率正逐年攀升&#xff0c;且出现低龄化现象。2020年&#xff0c;我国儿童青少年总体近视率竟高达52.7%&#xff0c;其中6岁儿童已达14.3%&#xff0c;小学生为35.6%&#xff0c;初中生为71.1…

Hue(1): Apache Hue 介绍

1 Hue 是什么 HUEHadoop User Experience Hue 是一个开源的 Apache Hadoop UI 系统&#xff0c;由 Cloudera Desktop 演化而来&#xff0c;最后 Cloudera 公司将其贡献给 Apache 基金会的 Hadoop 社区&#xff0c;它是基于Python Web 框架 Django 实现的。 通过使用 Hue&am…

GAMES101笔记:BRDF和渲染方程

BRDF : 双向反射分布函数(Bidirectional Reflectance Distribution Function) 描述从某个方向入射的能量反射到不同的方向上的能量的分布。 理解反射 从能量的角度理解反射。上图中&#xff0c;ωi\omega_iωi​方向入射的光线具有的Radiance&#xff0c;累积在微小面积dAdAd…

沉浸式 3D 场景下的多视点视频 增强算法研究

沉浸式 3D 场景下的多视点视频 增强算法研究研究内容图像质量增强为什么进行图像质量增强图像有损压缩技术多视点视频中的深度图像特点视点数目增强虚拟视点合成技术视点外推为什么进行视点数目增强主要贡献基于自适应残差网络的多视点压缩深度图像增强算法基于多约束编解码网络…

SautinSoft PDF Focus .Net 8.6.1 Crack

PDF Focus .Net 完整的 API 可在 .NET 平台上转换任何 PDF 文档, .Net 程序集提供 API 以将 PDF 转换为所有格式&#xff1a;DOCX、RTF、HTML、XML、文本、Excel、.Net 和 C# 中的图像。 介绍 PDF Focus .Net 旨在帮助您开发需要转换任何 PDF 文档的应用程序。看看PDF Focus .N…

2023年“华数杯”国际大学生数学建模A题完整思路

2023华数杯如期开赛&#xff0c;本次比赛作为美赛的模拟赛&#xff0c;赛题和比赛时间都和美赛高度相似&#xff0c;因此大家 完全可以当作一次美赛之前的练习赛进行。美赛的发题时间与华数杯一致&#xff0c;都是早晨六点&#xff0c;现已经将机器翻译的初步翻译 结果进行了分…

C#里最简单向文件追加文本的方法AppendAllText

C#里最简单向文件追加文本的方法AppendAllText 在开发的过程中,经常会碰到这样的问题,就是当一个文件没有创建时,就需要创建。但是文件已经创建了,就直接追加数据。 比如我们开发一个记录每天温度的软件, 每天都在固定的时间去记录一下这个温度,那么就需要在这个文件后面…

【第一章】SQL基础知识

目录 ​编辑 1. 认识SQL 1.1 SQL的标准 1.2 SQL的种类 1.3 SQL的功能 2. 常量 2.1 数字常量 2.2 字符串常量 2.3 日期和时间常量 2.4 符号常量 3. 变量 3.1 局部变量 3.2 全局变量 4. 运算符 4.1 算术运算符 4.2 比较运算符 4.3 逻辑运算符 4.4 按位运算符 …

Redis沙盒逃逸漏洞(CVE-2022-0543)复现以及流量特征分析

Redis简介 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值&#xff08;Key-Value&#xff09;存储数据库&#xff0c;并提供多种语言的API。 漏洞介绍 Redis 存在代码注入漏洞&#xff0c;攻击者可利用该漏…

Android MVVM之CreationExtras创建ViewModel的详解与使用

一、介绍 CreationExtras是Android api在Androidx-Lifecycle 在近期迈入到了 2.5.0 版本中。很多人第一眼看到&#xff0c;不知道这是个什么&#xff0c;看到会觉得云里雾里&#xff0c;无从下手&#xff0c;也不知道到底该怎么做。这个和现有的ViewModel搭配使用。他不能单独使…