一、工程搭建
使用IDEA新建Spring Boot 工程 spring-boot-emps,选择基本Web依赖
在entity包中增加Employee和Department实体类
@Data @NoArgsConstructor @AllArgsConstructor public class Employee { private Integer id; private String lastName; private String email; private Integer gender; private Department department; } 复制代码
@Data @NoArgsConstructor @AllArgsConstructor public class Department { private Integer id; private String departmentName; } 复制代码
在mapper包中增加对应的EmployeeMapper和DepartmentMapper类
@Repository public class EmployeeMapper { private static Map<Integer, Employee> employees = null; @Autowired private DepartmentMapper departmentDao; static{ employees = new HashMap<Integer, Employee>(); employees.put(1001, new Employee(1001, "Tony Stark", "stark@starkindustrymail.com", 1, new Department(101, "STARK INDUSTRIES"))); employees.put(1002, new Employee(1002, "Steve Rogers", "steve@gmail.com", 1, new Department(102, "S.H.I.E.L.D. "))); employees.put(1003, new Employee(1003, "Natasha Romanoff", "natash@gmail.com", 0, new Department(102, "S.H.I.E.L.D. "))); employees.put(1004, new Employee(1004, "Robert Bruce Banner", "banner@gmail.com", 1, new Department(103, "The Avengers"))); employees.put(1005, new Employee(1005, "Clint Barton", "clint@gmail.com", 1, new Department(102, "S.H.I.E.L.D. "))); } private static Integer initId = 1006; public void save(Employee employee){ if(employee.getId() == null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId())); employees.put(employee.getId(), employee); } public Collection<Employee> getAll(){ return employees.values(); } public Employee get(Integer id){ return employees.get(id); } public void delete(Integer id){ employees.remove(id); } } 复制代码
@Repository public class DepartmentMapper { private static Map<Integer, Department> departments = null; static{ departments = new HashMap<Integer, Department>(); departments.put(101, new Department(101, "STARK INDUSTRIES")); departments.put(102, new Department(102, "S.H.I.E.L.D. ")); departments.put(103, new Department(103, "The Avengers")); } public Collection<Department> getDepartments(){ return departments.values(); } public Department getDepartment(Integer id){ return departments.get(id); } } 复制代码
将Bootstrps模板和静态资源分别拷贝到templates文件夹和static文件夹中 要将 "/" 映射到templates下的index.html页面,可以新建一个HelloController,并新增一个方法将“/”映射到index.html页面,Thymeleaf已经做好了视图解析的配置
@Controller public class HelloController { @RequestMapping("/") public String hello(){ return "index"; } } 复制代码
重新启动应用,浏览器输入 localhost:8080
这样为每一个页面跳转都增加一个方法未免太过麻烦,最好是能像SSM中Spring MVC配置文件中配置映射;这时候就可以使用到配置类。
新建config包并增加自定义的Web MVC配置类LilithMvcConfig实现 WebMvcConfigurer,添加@Configuration注解,并在自定义的配置中添加视图映射
@Configuration public class LilithMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); } } 复制代码
将HelloController中的方法注释掉,重新启动应用,再次在浏览器中输入localhost:8080
静态资源引用改造
公共静态资源使用webjars代替
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.0.0</version> </dependency> 复制代码
私有静态资源使用Thymeleaf,在HTML页面头部添加Thymeleaf命名空间
xmlns:th="http://www.thymeleaf.org 复制代码
将所有的静态资源CSS、JS、PNG等资源全部改为使用Thymeleaf命名空间引用。
二、Spring Boot 国际化配置
Spring MVC 如何进行国际化配置的步骤
- 编写国际化配置文件
- 使用ResourceBundleMessageSource管理国际化资源文件
- JSP页面导入fmt命名空间,使用fmt:message取出国际化内容
Spring Boot进行国际化配置同样也需要编写国际化资源文件,并使用Thymeleaf模板引擎取出国际化内容
在resources目录下新建i18n文件夹,建立login.properties、login_zh_CN.properties、login_en_US.properties分别为默认显示的内容和中文内容以及英文内容
使用idea进行配置国际化,进入中文国际化配置文件
点击ok之后
就可以填写默认显示的内容和中文英文状态显示的内容
接着将这五项全部配置国际化既添加国际化内容
Spring Boot中包含了自动配置类MessageSourceAutoConfiguration,该类在 org.springframework.boot.autoconfigure.context包下。
MessageSource就是管理国际化资源文件的组件
setBasenames就是设置国际化资源文件的基础名,也就是去掉国家语言代码之后的名字
默认的国际化资源文件名的前缀是message
在application.properties配置文件中修改国际化文件名的前缀
spring.messages.basename=i18n.login 复制代码
Thymeleaf 官方文档中 4.1 Messages 提到使用#{}来获取消息内容
修改index.html页面,修改需要国际化的标签,修改时页面会出现国际化的提示
需要注意的是remember的国际配置要使用行内写法
<input type="checkbox" value="remember-me"> [[#{login.remember}]] 复制代码
重启应用,浏览器输入http://localhost:8080/
设置浏览器语言为英文
发送请求切换语言
国际化能显示不同的语言是因为Locale区域信息对象设置了不同的国家或地区,而LocaleResolver就是获取区域信息的对象
WebMvcAutoConfiguration自动配置类中配置了LocaleResolver区域解析器既如果配置类区域信息就是用配置的区域信息来实现国际化,否则就是用请求头的Accept Language中的区域信息来实现国际化,并且这个方法上标注了@ConditionalOnMissingBean,只要容器中有了自定义的区域解析器,Spring Boot自动配置的去解析器就不会导入容器中,自然也就不会生效了。
实际setDefaultLocale的区域就是从浏览器请求头中的“Accept-Language”中获取到的区域信息
想要点击页面的中英文连接实现语言切换那就不能使用自动配置类中实现的区域解析器,要自定义区域解析器
浏览器发送的请求头中会包含浏览器的语言
自定义一个区域信息解析器,根据链接上携带的区域信息切换语言
修改html页面中 中文 English连接,带上区域信息
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_CN')}">English</a> 复制代码
实现自定义的区域解析器
public class LilithLocaleResovler implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest request) { // 获取连接中携带的区域信息 String localeInfo = request.getParameter("l"); // 使用系统默认的 Locale locale = Locale.getDefault(); if (StringUtils.hasLength(localeInfo)){ String[] split = localeInfo.split("_"); // 使用携带的语言参数 locale = new Locale(split[0],split[1]); } return locale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { } } 复制代码
在LilithMvcConfig中增加代码,将自定义的区域信息解析器注册到容器中
@Bean public LocaleResolver localeResolver(){ LilithLocaleResovler localeResovler = new LilithLocaleResovler(); return localeResovler; } 复制代码
重新启动程序,浏览器进入首页
点击中文和English可以成功实现语言切换