Spring Boot页面国际化

GitHub:SpringBootDemo
Gitee:SpringBootDemo
微信公众号:在这里插入图片描述

0 开发环境

  • JDK:1.8
  • Spring Boot:2.7.18

1 检查配置

确保File -> Settings… -> Editor -> File Encodings 配置中编码为UTF-8,否则后续会出现乱码

在这里插入图片描述

2 安装插件

安装Resource Bundle Editor插件后,Resource Bundle就可以可视化编程了

在这里插入图片描述

3 新建配置文件

3.1 resources下新建i18n目录

其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数,是“国际化”的简称

3.2 i18n下新建配置文件

新建login.properties国际化默认配置文件,再新建login_zh_CH.properties中文配置文件,此时,系统会自动识别到国际化配置,将文件合并目录并切换到国际化视图。

在这里插入图片描述

我们就可以直接在**Resource Bundle ‘login’**文件夹上右键添加其他语言配置文件

在这里插入图片描述

比如添加英语配置文件

在这里插入图片描述

3.3 编写配置文件

打开其中一个配置文件,切换到Resource Bundle视图,点击**+**,即可添加配置

在这里插入图片描述

比如添加login.username配置,添加完成后,页面上会出现3个录入框,可配置不同语言的值

在这里插入图片描述

配置完成后,所有配置文件都会自动配置上对应值,比如

在这里插入图片描述

完整配置如下

login.btn=登录
login.error=用户名或密码错误
login.password=密码
login.username=用户名

4 配置yml

spring:
  messages:
    basename: i18n.login

5 页面国际化

5.1 引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

5.2 新建登录页

resources目录下新建templates目录,再新建login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title></title>

    <style>
        .container {
            width: 300px;
            margin: auto;
            padding: 40px;
            border: 1px solid #ccc;
            background-color: white;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        label {
            display: block;
            margin-bottom: 10px;
        }

        input {
            width: 100%;
            padding: 6px;
            border: 1px solid #ccc;
            outline: none;
        }

        button {
            width: 100%;
            padding: 10px;
            color: white;
            background-color: #4CAF50;
            cursor: pointer;
            border: none;
            outline: none;
        }

        .language {
            width: 100%;
            text-align: center;
            margin-top: 10px;
        }

        .language a {
            color: blue;
            cursor: pointer;
            padding: 10px;
        }

        button:hover,
        a:hover {
            opacity: 0.9;
        }
    </style>
</head>
<body>
<div class="container">
    <form action="" method="post">
        <label for="username" th:text="#{login.username}"></label>
        <input type="text" id="username" name="username"><br><br>

        <label for="password" th:text="#{login.password}"></label>
        <input type="password" id="password" name="password"><br><br>

        <button type="submit" th:text="#{login.btn}"></button>
    </form>
</div>
<div class="language">
    <a th:href="@{/login.html(l=zh_CN)}">中文</a>
    <a th:href="@{/login.html(l=en_US)}">English</a>
</div>
</body>
</html>

5.3 新建Controller

@Controller
public class LoginController {

    @GetMapping(value = "login.html")
    public String login() {
        return "login";
    }
}

5.4 新建配置类

页面能够实现国际化,是通过Locale区域信息对象来实现的。

WebMvcAutoConfiguration中配置了默认的localeResolver,我们自定义一个LocaleResolver并注入容器,来替换默认的localeResolver。

注意:注入的bean名称必须为localeResolver,因为**@ConditionalOnMissingBean**会判断是否已经注入了bean

在这里插入图片描述

@Configuration
public class GlobalLocaleResolver implements LocaleResolver {

    /**
     * 解析请求
     *
     * @param request
     * @return
     */
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        //默认地区
        Locale locale = request.getLocale();

        //获取请求中的语言参数
        String language = request.getParameter("l");
        if (!StringUtils.isEmpty(language)) {
            //zh_CN 国家_地区
            String[] values = language.split("_");
            locale = new Locale(values[0], values[1]);
        }

        return locale;
    }

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

    }

    @Bean
    public LocaleResolver localeResolver() {
        return new GlobalLocaleResolver();
    }
}

5.5 测试

启动服务,浏览器访问127.0.0.1:8090/login.html

在这里插入图片描述

切换英语:

在这里插入图片描述

切换中文:

在这里插入图片描述

页面可正常切换中英文,测试通过。

7 返回信息国际化

7.1 新建工具类

public class I18nUtils {

    public static String getMessage(String key) {
        Locale locale = LocaleContextHolder.getLocale();
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n/login");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource.getMessage(key, null, locale);
    }
}

7.2 新建Service

@Service
public class UserService {

    public String login() {
        return I18nUtils.getMessage("login.error");
    }
}

7.3 新建Controller

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping(value = "login")
    public String login() {
        return userService.login();
    }
}

7.4 测试

启动服务,Postman请求,默认中文如下:

在这里插入图片描述

附:HTTP请求头Accept-Language含义

Accept-Language:zh-CN,zh;q=0.9

Accept-Language:浏览器支持的语言类型

zh-CN:简体中文

zh:中国地区

q:用户对该范围指定的语言的偏好,为空则默认为1,范围[0, 1],值越大,权重越大

英语如下:

在这里插入图片描述

根据传入的地区信息,返回对应语言的提示信息,测试通过。

8 返回信息拼接参数

上面我们正常返回了中英文的用户名或密码错误,现在升级一下,返回类似 xxx用户名或密码错误

8.1 调整配置文件

在这里插入图片描述

8.2 调整工具类

public class I18nUtils {

    public static String getMessage(String key) {
        Locale locale = LocaleContextHolder.getLocale();
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n/login");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource.getMessage(key, null, locale);
    }

    public static String getMessage(String key, Object... args) {
        Locale locale = LocaleContextHolder.getLocale();
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n/login");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource.getMessage(key, args, locale);
    }
}

8.3 调整Service

@Service
public class UserService {

    public String login() {
        return I18nUtils.getMessage("login.error");
    }

    public String loginSuccess(String username) {
        return I18nUtils.getMessage("login.success", username, new Date());
    }
}

8.4 调整Controller

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping(value = "login")
    public String login() {
        return userService.login();
    }

    @PostMapping(value = "loginSuccess")
    public String loginSuccess(@RequestParam("username") String username) {
        return userService.loginSuccess(username);
    }
}

8.5 测试

启动服务,Postman请求,中文如下:

在这里插入图片描述

英语如下:

在这里插入图片描述

根据传入的地区信息,返回对应语言的提示信息,且正确组装传入的参数,测试通过。

至此,国际化完成,且测试通过。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python | Leetcode Python题解之第2题两数相加

题目&#xff1a; 题解&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optiona…

攻防世界-easyphp

题目信息 题目信息如下&#xff1a; 可以看到&#xff0c;key1和key2的值都为1的时候&#xff0c;才能拿到flag。再网上看&#xff0c;发现key1和key2的值取决于a,b和c的值。 <?php highlight_file(__FILE__); $key1 0; $key2 0;$a $_GET[a]; $b $_GET[b];if(isset($a…

Java编程实战:疫情物资分配系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

分治——归并排序算法

例题一 解法&#xff08;归并排序&#xff09;&#xff1a; 算法思路&#xff1a; 归并排序的流程充分的体现了「分⽽治之」的思想&#xff0c;⼤体过程分为两步&#xff1a; ◦ 分&#xff1a;将数组⼀分为⼆为两部分&#xff0c;⼀直分解到数组的⻓度为 1 &#xff0c;使…

vulhub打靶记录——driftingbox

文章目录 主机发现端口扫描目录扫描爆破子域名提权总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.56.0/24192.168.56.1&#xff1a;主机IP&#xff1b;192.168.56.100&#xff1a;DHCP服务器IP&#xff1b;192.168.56.101…

回溯算法|39.组合总和

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum target) {result.push_back…

IDEA 详细设置

详细设置 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 系统设置 默认启动项目配置 启动IDEA时&#xff0c;默认自动打开上次开发的项目&#xff1f;还是自己选择&#xff1f; 如果去掉Reopen projects on startup前面的对勾&#xff0c;每次启动IDEA就会…

【软件安装教程】IDEA

【软件安装教程】IDEA 系统: Windows11 64位版本: ideaIC-2023.3.6官方地址: Jetbrains网盘地址: 百度网盘 下载 处于成本考虑就直接用社区版了&#xff0c;如果专业版配置过程都一样 安装 双击下载的文件 根据电脑存储选择一个合适的地址后点击下一步 选择配置&#…

鸿蒙OS(ArkTS) 案例:【使用http网络请求框架加载验证码】

需求&#xff1a;加载验证码&#xff1b;1.下载验证码图像文件&#xff1b;2.获取header里面验证码ID 踩坑--踩坑--踩坑 根据文档使用 request.downloadFile 请求&#xff0c;官方示例: // pages/xxx.ets // 将网络资源文件下载到应用文件目录并读取一段内容 import common …

Mac使用“Workstation”安装双系统

## 选择虚拟机 Mac推荐使用“VMware” 优点 1.个人版是免费的 2.界面清晰&#xff0c;运行流程 3.使用人群广&#xff0c;遇到问题容易解决 版本比较 VMware Workstation Pro 和 VMware Workstation Player 个人使用推荐 VMware Workstation Player &#xff0c;因为个人的…

二十四种设计模式与六大设计原则(四):【状态模式、原型模式、中介者模式、解释器模式、享元模式、备忘录模式】的定义、举例说明、核心思想、适用场景和优缺点

接上次博客&#xff1a;二十四种设计模式与六大设计原则&#xff08;三&#xff09;&#xff1a;【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 状态模式【State Pattern】 定义 举…

Python之numpy:常用运算广播机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、numpy运算二、常见运算1.ufunc函数2.复合赋值运算符3.判断符 二、聚合函数三、唯一化、集合四、numpy广播机制 一、numpy运算 numpy有两种基本对象&#xff1a…

【linux】AMD GPU和NVIDIA GPU驱动安装

AMD GPUs - Radeon™ PRO W7900的驱动安装过程 要在Linux系统上安装AMD的Radeon™ PRO W7900显卡驱动程序&#xff0c;通常需要执行以下步骤。以下示例基于Ubuntu系统&#xff1b;其他Linux发行版的具体步骤可能有所不同。 1. 更新系统 打开一个终端窗口&#xff0c;并输入…

redis学习-主从复制和哨兵模式

目录 1. 主从复制&#xff0c;读写分离 1.1 介绍 1.2 使用命令介绍 1.3 实现 1.4全量复制和增量复制 2.哨兵模式 1. 主从复制&#xff0c;读写分离 1.1 介绍 指的是将一台redis服务器中的数据复制到其他redis服务器&#xff0c;前者称为主机&#xff0c;后者称为从机&#xf…

C++刷题篇——04找等值元素

一、题目 二、解题思路 1、分割后放进二维数组 2、使用map&#xff0c;key为数值&#xff0c;value为其坐标 3、遍历二维数组元素&#xff0c;再在map中找该元素对应的value值&#xff08;二维数组形式&#xff09;&#xff0c;倘若value.size为1&#xff0c;那直接返回-1&…

嵌入式第一部分-第一集:ARM那些你得知道的事

ARM&#xff1a;Advanced RISC Machine&#xff0c;先进精简指令集机器 ARM公司只做设计&#xff0c;不生产。 国内IC生产厂商&#xff1a;华为海思、全志、瑞芯微、MTK&#xff08;联发科&#xff09; 扩展&#xff1a;ARM的商业模式了解。 使用三星S5PV210开发板进行视频的讲…

改进的图像LSB加密算法:Matrix encoding embedding

参考文献1 Visually secure image encryption using adaptive-thresholding sparsification and parallel compressive sensing 算法实现 简单说明 算法步骤概述 定义函数f:这个函数用于计算给定码字b的一个特定值,此值将与秘密信息x进行比较。这个计算涉及到将码字b的每一…

基于springboot+vue+Mysql的新生宿舍管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Redis命令-Set命令

基础篇Redis 4.7 Redis命令-Set命令 Redis的Set结构与Java中的HashSet类似&#xff0c;可以看做是一个value为null的HashMap。因为也是一个hash表&#xff0c;因此具备与HashSet类似的特征&#xff1a; 无序元素不可重复查找快支持交集.并集.差集等功能 Set类型的常见命令 …

Linux:查看系统各个组件性能的方法

查看cpu top 还有更为直观的 htop 可以同时看到&#xff0c;内存占用&#xff0c;cpu占用&#xff0c;交换内存的占用 vmstat 是比较综合的可以看到内存&#xff0c;交换内存&#xff0c;io吞吐&#xff0c;系统&#xff0c;cpu 查看内存 free -h 可以看懂内存的使用情况 …