SpringBoot--thymeleaf使用和页面国际化

Posted dxj1016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot--thymeleaf使用和页面国际化相关的知识,希望对你有一定的参考价值。

1、准备工作

  1. 新建springboot项目,命名为springboot-employee-management-system
    在这里插入图片描述
  2. 选择需要的配置模块
    在这里插入图片描述
  3. 创建controller层,写一个HelloController测试一下
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello world";
    }
}
  1. 启动项目,测试结果
    在这里插入图片描述
  2. 将静态资源导入进来
    在这里插入图片描述
    index.html页面:index.html页面
    在这里插入图片描述
    dashboard.html页面:dashboard.html页面
    在这里插入图片描述
    404.html页面直接进去复制index中的内容即可:404.html页面
    list.html页面:暂时先拿dashboard.html页面的中的代码
  3. 导入lombok依赖(要有lombok插件,如果没有先到setting去下载)
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
  1. 创建pojo层,创建Department 实体类和Employee 实体类
//部门表
@Data
@AllArgsConstructor//有参构造器
@NoArgsConstructor//无参构造器
public class Department {
    private Integer id;
    private String departmentName;
}
//员工表
@Data
@NoArgsConstructor
public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;//0:女 1:男
    private Department department;
    private Date birth;

    public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
//        默认的日期
        this.birth = new Date();
    }
}
  1. 创建dao层,创建DepartmentDao 和EmployeeDao
//部门dao
@Repository
public class DepartmentDao {
    //    模拟数据库中的数据
    private static Map<Integer, Department> departmentMap = null;
    static{
        departmentMap = new HashMap<Integer, Department>();//创建一个部门表
        departmentMap.put(101, new Department(101, "教学部"));
        departmentMap.put(102, new Department(102, "市场部"));
        departmentMap.put(103, new Department(103, "教研部"));
        departmentMap.put(104, new Department(104, "运营部"));
        departmentMap.put(105, new Department(105, "后勤部"));
    }
    //    获得所有部门信息
    public Collection<Department> getDepartments() {
        return departmentMap.values();
    }
    //    通过id得到部门
    public Department getDepartmentById(Integer id) {
        return departmentMap.get(id);
    }
}
//员工dao
@Repository
public class EmployeeDao {
    //    模拟数据库中的数据
    private static Map<Integer, Employee> employeeMap = null;
    //    员工有所属的部门
    @Autowired
    private DepartmentDao departmentDao;//要将这个注入过来,dao层要添加注解应该添加@Repository,这个属性就可以使用注解@Autowired

    static {
        employeeMap = new HashMap<Integer, Employee>();//创建一个员工表
        employeeMap.put(1001, new Employee(1001, "A", "1278001208@qq.com", 0, new Department(101, "教学部")));
        employeeMap.put(1002, new Employee(1002, "B", "1278002208@qq.com", 1, new Department(102, "市场部")));
        employeeMap.put(1003, new Employee(1003, "C", "1278003208@qq.com", 0, new Department(103, "教研部")));
        employeeMap.put(1004, new Employee(1004, "D", "1278004208@qq.com", 1, new Department(104, "运营部")));
        employeeMap.put(1005, new Employee(1005, "E", "1278004208@qq.com", 0, new Department(105, "后勤部")));
    }
    //    主键自增
    private static Integer initId = 1006;

    //    增加一个员工
    public void save(Employee employee) {
        if (employee.getId() == null) {
            employee.setId(initId++);
   }employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
        employeeMap.put(employee.getId(), employee);
    }
    //    查询全部员工信息
    public Collection<Employee> getAll() {
        return employeeMap.values();
    }
    //    通过id查询员工
    public Employee getEmployeeById(Integer id) {
        return employeeMap.get(id);
    }
    //    删除员工通过id
    public void delete(Integer id) {
        employeeMap.remove(id);
    }
}

2、首页实现

  1. 写首页Controller
@Controller
public class IndexController {

    @RequestMapping({"/", "index.html"})
    public String index() {
        return "index";
    }
}
  1. 启动项目并访问:http://localhost:8080/,可以看到如下页面
    在这里插入图片描述
  2. 自己写配置类,创建config文件夹,创建MyMvcConfig配置类
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//    添加视图控制器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");

    }
}
  1. 把上面写的IndexController去掉重启项目,测试看结果
    在这里插入图片描述
  2. 要使用thymeleaf,需要在html文件中导入命名空间的约束,方便提示
 xmlns:th="http://www.thymeleaf.org"
  1. 到index.html文件中修改两处地方的代码
    在这里插入图片描述
  2. 到properties配置文件中关闭模板引擎的缓存
    在这里插入图片描述
  3. 重新启动项目访问:http://localhsot:8080/,可看到页面出来了
    在这里插入图片描述
  4. 去404.html页面修改代码
    在这里插入图片描述
  5. 去dashboard.html页面修改代码
    在这里插入图片描述
  6. 去list.html页面修改代码
    在这里插入图片描述
  7. 如果我在配置文件properties中添加下面代码
    在这里插入图片描述
  8. 启动项目测试
    在这里插入图片描述
  9. 右键查看源码发现他会自动帮我们配置到前面的路径/dxj1016
    在这里插入图片描述

3、页面国际化

springBoot国际化就是指页面可以按照中英文切换显示。实现步骤大致分为三步:1,配置国际化文件2.写国际化类添加组键中3.页面展示。大致原理就是LocaleResolver根据获取请求头中的信息,进行判断。

3.1、准备工作

  1. 先在IDEA中统一设置properties的编码问题!不然页面可能乱码
    在这里插入图片描述
  2. 编写国际化配置文件,抽取页面需要显示的国际化页面消息。我们可以去登录页面查看一下,哪些内容我们需要编写国际化的配置!

3.2、配置文件编写

  1. 我们在resources资源文件下新建一个i18n目录,存放国际化配置文件
  2. 建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作;文件夹变了!
    在这里插入图片描述
  3. 接下来通过右键Resource Bundle ‘login’–>New–>Add Property Files to Resource Bundle新建一个login_en_US.properties文件。
    在这里插入图片描述
    在这里插入图片描述
  4. 最后文件结构如下:
    在这里插入图片描述
  5. 接下来,我们就来编写配置,我们可以看到idea下面有另外一个视图;
    在这里插入图片描述
  6. 这个视图我们点击 + 号就可以直接添加属性了;我们新建一个login.tip,可以看到边上有三个文件框可以输入。添加一下首页的内容
    在这里插入图片描述
  7. 然后依次添加其他页面内容即可!
    在这里插入图片描述
  8. 然后去查看我们的配置文件;

login.properties :默认

login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名

英文:

login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username

中文:

login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名

OK,配置文件步骤搞定

3.3、配置文件生效探究

  • 我们去看一下SpringBoot对国际化的自动配置!这里又涉及到一个类:MessageSourceAutoConfiguration

  • 里面有一个方法,这里发现SpringBoot已经自动配置好了管理我们国际化资源文件的组件 ResourceBundleMessageSource;

// 获取 properties 传递过来的值进行判断
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    if (StringUtils.hasText(properties.getBasename())) {
        // 设置国际化文件的基础名(去掉语言国家代码的)
        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());
    }
//这里是到properties中去找
    messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
    messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
    return messageSource;
}

我们真实的情况是放在了i18n目录下,所以我们要去application.properties文件中配置这个messages的路径;
在这里插入图片描述

# 我们的配置文件的真实位置
spring.messages.basename=i18n.login

配置页面国际化值
去index.html页面获取国际化的值,查看Thymeleaf的文档,找到message取值操作为:#{…}。我们去页面测试下:
到index.html页面将页面上的属性都用thymeleaf格式。
在这里插入图片描述
我们可以去启动项目,访问一下:http://localhost:8080/dxj1016;因为在前面有配置了路径dxj1016,如果没有配置那么就是访问:http://localhost:8080/,发现已经自动识别为中文的了!
在这里插入图片描述

但是我们想要更好!可以根据按钮自动切换中文英文!

配置国际化解析

  • 在Spring中有一个国际化的Locale (区域信息对象);里面有一个叫做LocaleResolver (获取区域信息对象)的解析器!

  • 我们去我们webmvc自动配置文件,寻找一下!看到SpringBoot默认配置:

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
    // 容器中没有就自己配,有的话就用用户配置的
    if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
        return new FixedLocaleResolver(this.mvcProperties.getLocale());
    }
    // 接收头国际化分解;如果用户没有配置,就使用这个
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
    return localeResolver;
}

AcceptHeaderLocaleResolver 这个类中有一个方法


public Locale resolveLocale(HttpServletRequest request) {
    Locale defaultLocale = this.getDefaultLocale();
    // 默认的就是根据请求头带来的区域信息获取Locale进行国际化
    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 {
                return defaultLocale != null ? defaultLocale : requestLocale;
            }
        } else {
            return requestLocale;
        }
    }
}
  • 那假如我们现在想点击链接让我们的国际化资源生效,就需要让我们自己的Locale生效!

  • 我们去自己写一个自己的LocaleResolver,可以在链接上携带区域信息!

  • 修改一下前端页面的跳转连接:

<!-- 这里传入参数不需要使用 ?使用 (key=value)-->
<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>
  • 我们去写一个处理的组件类!

package com.kuang.component;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

//可以在链接上携带区域信息
public class MyLocaleResolver implements LocaleResolver {

    //解析请求
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        //获取请求中的语言参数
        String language = request.getParameter("l");
        Locale locale = Locale.getDefault(); // 如果没有获取到就使用系统默认的
        //如果请求链接不为空,携带了国际化的参数
        if (!StringUtils.isEmpty(language)){
            //分割请求参数:zh_CN
            String[] split = language.split("_");
            //国家,地区
            locale = new Locale(split[0],split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}
  1. 为了让我们的区域化信息能够生效,我们需要再配置一下这个组件!在我们自己的MyMvcConofig下添加bean;
//自定义的国际化就生效了
@Bean
public LocaleResolver localeResolver(){
    return new MyLocaleResolver();
}

在这里插入图片描述
2. 重启项目
在这里插入图片描述
总结:
在这里插入图片描述

4、员工管理系统–登录功能实现

  1. 写个LoginController
@Controller
public class LoginController {
    @RequestMapping("/user/login")
    @ResponseBody
    public String login() {
        return "OK";
    }
}
  1. 修改index.html页面
    在这里插入图片描述
  2. 启动项目测试:
    在这里插入图片描述
  3. 给index.html页面的添加name属性
    在这里插入图片描述
  4. LoginController代码
  5. 启动项目,测试:http://localhost:8080/dxj1016/,到了登录页面,输入的用户名不为空和密码是123456的话就会跳转到设置的dashboard页面
    在这里插入图片描述
  6. 输入的密码错误或者用户名为空,他没有任何提示,在index.html页面加个提示信息。
    在这里插入图片描述
  7. 启动测试,输入错误密码
    Springboot+Thymeleaf+layui框架的配置与使用

    SpringBoot + Thymeleaf + Security Dialect 怎么配置?

    springboot thymeleaf引入css和js必须添加th吗

    Intellij+Springboot+Thymeleaf+gradle - 自动重载html资源

    springboot+thymeleaf简单使用

    SpringBoot--Thymeleaf入门使用